IOT协议对接
authordxy <1731678236qq.com>
Thu, 14 Aug 2025 01:47:02 +0000 (09:47 +0800)
committerdxy <1731678236qq.com>
Thu, 14 Aug 2025 01:47:02 +0000 (09:47 +0800)
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/Makefile
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ai_VC.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ai_alarm.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/constants.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/main_init.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/mgr.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/motor.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/protocol.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ui.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/voice_record.py [new file with mode: 0644]

index 80fbcdd..adea516 100644 (file)
@@ -967,6 +967,7 @@ frozen_mpy_list =   $(BUILD)/_boot.mpy \
                                        $(BUILD)/motor.mpy \
                                        $(BUILD)/ai_VC.mpy \
                                        $(BUILD)/ai_alarm.mpy \
+                                       $(BUILD)/voice_record.mpy \
 
 endif
 
index f66522a..2f02ca4 100644 (file)
@@ -40,7 +40,7 @@ try:
 except Exception as e:
     usys.print_exception(e)
     import ai_alarm as _ai_alarm
-#dev_type = "G10"
+# dev_type = "G10"
 dev_type = "7PIN_BK"#小瑞
 #dev_type = "7PIN_BK_coze"#k扣子小瑞
 #dev_type = "7PIN_BK_EU"#英文小瑞
@@ -64,9 +64,10 @@ class AI_led(Abstract):
             self.led_green = Pin(Pin.GPIO8, Pin.OUT, Pin.PULL_PD, 1)
             self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
         else:
-            self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
-            self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
-            self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
+            self.led_red = Pin(Pin.GPIO28, Pin.OUT, Pin.PULL_PD, 0)
+            #self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
+            self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1)
+            self.led_blue = Pin(Pin.GPIO30, Pin.OUT, Pin.PULL_PD, 1)
 
         #=1 红灯闪,=2白灯闪,=3绿灯闪,=4全部灯闪
         self.led_flicker_flag = 0
@@ -204,34 +205,368 @@ def set_ipv4_datacall():
                        print('已经配置为IPv4')
        else:
                print('获取PDP Context失败。')
+
+#HEARDER+TOTALLEN+DATELEN+DATA
+HEARDER = "FFFE"
+TOTALLEN = "00000000"
+DATELEN = "0000"
+DATA = {}
 class AI_UART():
     #串口命令通道
     def __init__(self):
-        self.AI_uart = UART(UART.UART4, 115200, 8, 0, 1, 0)
+        self.AI_uart = UART(UART.UART4, 230400, 8, 0, 1, 0)
         self.AI_uart.set_callback(self.uart_call)
+        EventMesh.subscribe("led_r_open",self.led_r_open) 
+        EventMesh.subscribe("led_g_open",self.led_g_open)
+        EventMesh.subscribe("led_b_open",self.led_b_open)
+        EventMesh.subscribe("led_rgb_open",self.led_rgb_open)
+        EventMesh.subscribe("led_close",self.led_close)
+        EventMesh.subscribe("up_datat_bt",self.up_datat_bt)
+        EventMesh.subscribe("start_ota",self.start_ota)
+        EventMesh.subscribe("end_ota",self.end_ota)
+        EventMesh.subscribe("send_ble_adv_switch",self.send_ble_adv_switch)
+        EventMesh.subscribe("send_ble_adv_switch_to_ble",self.send_ble_adv_switch_to_ble)
+        EventMesh.subscribe("send_ble_scan",self.send_ble_scan)
+        EventMesh.subscribe("send_connect_bt_mac",self.send_connect_bt_mac)
+        EventMesh.subscribe("send_disconnect_bt_mac",self.send_disconnect_bt_mac)
+        EventMesh.subscribe("send_imei_to_ble",self.send_imei_to_ble)
+        self.uart_timer = osTimer()
+        self.uart_timer_count = 0
+        self.bt_ota_flag = 0
+        self.read_ack_flag = 0
+        self.ping_json_str = {}
+        self.ping_json_str_tmp =""
+        self.read_uart_data = ""
+    def send_ble_adv_switch_to_ble(self,event,msg):
+        json_data = \
+        {
+            
+            "event": "switch_bt_state",
+            "data":{
+                "switch_bt_state":msg
+            }   
+           
+        }
+        json_str  =ujson.dumps(json_data)
+        self.send_data(json_str)
+        pass
+    def send_imei_to_ble(self,event,msg):
+        imei  = modem.getDevImei()
+        json_data = \
+        {
+            
+            "event": "imei",
+            "data":str(imei)
+           
+        }
+        json_str  =ujson.dumps(json_data)
+        print("send imei:{}".format(json_str))
+        self.send_data(json_str)
+        pass
+    def send_connect_bt_mac(self,event,msg):
+        json_data = \
+        {
+            "event": "connect_bt",
+            "data":msg
+        }
+        json_str =ujson.dumps(json_data)
+        self.send_data(json_str)
+        pass
+    def send_disconnect_bt_mac(self,event,msg):
+        json_data = \
+        {
+            "event": "disconnect_bt",
+            "data":msg
+        }
+        json_str =ujson.dumps(json_data)
+        self.send_data(json_str)
+        pass
+    def uart_timer_cb(self, *args, **kwargs):
+        self.uart_timer_count+=1
+        if self.uart_timer_count >40:
+            self.read_uart_data = ""
+        if self.uart_timer_count >200:
+            self.read_uart_data = ""
+            self.uart_timer.stop()
     def uart_call(self,para):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.pares_uart_data})
         #print("ai_uart:{}".format(para))  
     def pares_uart_data(self):  
         uart_data = self.AI_uart.read()
+        self.uart_timer.start(10, 1, self.uart_timer_cb)
+        self.uart_timer_count = 0
+        ack_flag = 0#是否要返回ack
         print("uart_data:{}",uart_data)
         uart_data_str = uart_data.decode('utf-8')
-        if uart_data_str.find("AI_KEY_PRESS")!= -1: 
-            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})  
-        if uart_data_str.find("AI_PWR_PRESS")!= -1: 
-            EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release})  
+        self.read_uart_data = self.read_uart_data +uart_data_str
+        try:
+            ujson.loads(self.read_uart_data)
+        except Exception as e:
+            print("json数据不完整:self.read_uart_data{}".format(self.read_uart_data))
+            usys.print_exception(e)
+            return
+        self.uart_timer.stop()
+        self.uart_timer_count = 0
+        self.playload_data(self.read_uart_data)
+        
+        # print("uart_data_str:{}",uart_data_str)
+        # if len(uart_data_str) < (HEARDER+1+1):
+        #     return
+        # head = uart_data_str[0:4]
+        # pack_flag = uart_data_str[4:5]
+        # recvflag = uart_data_str[5:6]
+        
+        
+        # if head == HEARDER:
+        #     if pack_flag == "1": #分包数据
+        #         if recvflag == "1": #未发送完成
+        #             self.ping_json_str_tmp+=uart_data_str[6:]
+        #             pass
+        #         else:
+        #             self.playload_data(self.ping_json_str_tmp)
+        #             pass
+        #     else:
+        #         self.playload_data(uart_data_str[6:])
+                    
+        # else:
+        #    print("uart is not FFFE:") 
+
+    def playload_data(self,msg):
+        ack_flag=0
+        try:
+            print("playload_data:{}".format(msg))
+            jsload_data =  ujson.loads(msg)
+        #print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
+        
+            if jsload_data["event"] == "AI_KEY_PRESS" :#AI按键按下
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})  
+                ack_flag = 1
+            elif jsload_data["event"] == "AI_PWR_PRESS" :#电源按键按下
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release})  
+                ack_flag = 1
+            elif jsload_data["event"] == "bt_scan_rest":#扫描列表
+                EventMesh.publish("send_bt_scan_list",jsload_data)
+            elif jsload_data["event"]=="bt_connect_single":
+                EventMesh.publish("save_bt_connect_list",jsload_data)
+
+            elif jsload_data["event"] == "ack" :#电源按键按下
+                self.read_ack_flag = 1
+            if ack_flag == 1:
+                self.send_ack()
+            self.read_uart_data = ""
+        except Exception as e:
+            usys.print_exception(e)
+            self.read_uart_data = ""
+
+
+    def send_ble_adv_switch(self,event,msg):
+        # // {
+        #     //     "event":"switch_bt_state",
+        #     //     "data":{
+        #     //         "switch_bt_state":"0"
+        #     //     }
+        #     // } #格式
+        json_data = \
+        {
+            
+            "event": "switch_bt_state",
+            "data":{
+                "switch_bt_state":msg
+            }   
+           
+        }
+        json_str  =ujson.dumps(json_data)
+        print("send_ble_adv_switch{}".format(json_str))
+        self.send_data(json_str)
+        pass
+    def send_ble_scan(self,event,msg):
+        # // {
+        #     //     "event":"switch_bt_state",
+        #     //     "data":{
+        #     //         "switch_bt_state":"0"
+        #     //     }
+        #     // } #格式
+        json_data = \
+        {
+            
+            "event": "bt_scan",
+            "data":msg 
+           
+        }
+        json_str  =ujson.dumps(json_data)
+        print("send_ble_adv_switch{}".format(json_str))
+        self.send_data(json_str)
+        pass
+    def send_data(self,str_data):
+        if self.bt_ota_flag == 1:
+            return
+        EventMesh.publish("wakeup_BT")
+        self.AI_uart.write(str_data)
+    def led_r_open(self,event=None,msg=None):
+        json_data = \
+        {
+            
+            "event": "led_r_open",
+                
+           
+        }
+        json_str  =ujson.dumps(json_data)
+        print("led_r_open{}".format(json_str))
+        self.send_data(json_str)
+    def led_g_open(self,event=None,msg=None):
+        json_data = \
+        {
+
+            "event": "led_g_open",
+
+        }
+        json_str  =ujson.dumps(json_data)
+        print("led_g_open{}".format(json_str))
+        self.send_data(json_str)
+    def led_b_open(self,event=None,msg=None):
+        json_data = \
+        {
+
+            "event": "led_b_open",
+   
+        }
+        json_str  =ujson.dumps(json_data)
+        print("led_b_open{}".format(json_str))
+        self.send_data(json_str)
+    def led_rgb_open(self,event=None,msg=None):
+        json_data = \
+        {
+
+            "event": "led_rgb_open",
+
+        }
+        json_str  =ujson.dumps(json_data)
+        print("led_rgb_open{}".format(json_str))
+        self.send_data(json_str)
+    def led_close(self,event=None,msg=None):
+        json_data = \
+        {
+
+            "event": "led_close",
+
+        }
+        json_str  =ujson.dumps(json_data)
+        print("led_close{}".format(json_str))
+        self.send_data(json_str)
+        
+    def send_ack(self):
+        json_data = \
+        {
+
+            "event": "ack",
+
+        }
+        json_str  =ujson.dumps(json_data)
+        print("send_ack{}".format(json_str))
+        self.send_data(json_str)
     def AI_key_press(self):
         self.check_rest_timer_count = 0
         print("AI_key_press")
         EventMesh.publish("AI_key_press")
 
-
-        
     def pwk_key_release(self):
         self.check_rest_timer_count = 0
         #print("pwk_key_release")
         EventMesh.publish("pwk_key_release")
 
+    def start_ota(self,event=None,msg=None):#通过串口给蓝牙升级
+
+        print("start_ota!!!")
+        print("start_ota!!!")
+        json_data = \
+        {
+            "event": "ota_start",
+        }
+        json_str  =ujson.dumps(json_data)
+        self.AI_uart.write(json_str)
+        print(json_str)
+        count =100
+        while True:
+            count -=1
+            if count <=0 or self.read_ack_flag == 1:
+                break
+            utime.sleep_ms(1)
+        print("start_ota count:{}!!!".format(count))
+
+    def end_ota(self,event=None,msg=None):#通过串口给蓝牙升级
+
+        print("end_ota!!!")
+        print("end_ota!!!")
+        json_data = \
+        {
+            "event": "ota_end",
+        }
+        json_str  =ujson.dumps(json_data)
+        self.AI_uart.write(json_str)
+        print(json_str)
+        count =100
+        while True:
+            count -=1
+            if count <=0 or self.read_ack_flag == 1:
+                break
+            utime.sleep_ms(1)
+        print("end_ota count:{}!!!".format(count))
+
+    def up_datat_bt(self,event=None,msg=None):#通过串口给蓝牙升级
+        print("up_datat_bt!!!:url:{}".format(msg))
+        print("up_datat_bt!!!")
+        print("up_datat_bt!!!")
+        self.bt_ota_flag = 1
+        self.read_ack_flag = 0
+        
+        json_data = \
+        {
+            "event": "ota_start",
+        }
+        json_str  =ujson.dumps(json_data)
+        self.AI_uart.write(json_str)
+        print(json_str)
+        count =100
+        while True:
+            count -=1
+            if count <=0 or self.read_ack_flag == 1:
+                break
+            utime.sleep_ms(1)
+        headers_T = {"Content-Type":"application/octet-stream"}
+        response = request.get(url = msg,headers=headers_T,decode = False)
+        for i in response.content:
+            self.read_ack_flag = 0
+            data = base64.b64encode(i)
+            json_data = \
+            {
+                "event": "ota_data",
+                "update":data
+            }
+            json_str  =ujson.dumps(json_data)
+            self.AI_uart.write(json_str)
+            #utime.sleep_ms(100)
+            count =500
+            while True:
+                count -=1
+                if count <=0 or self.read_ack_flag == 1:
+                    break
+                utime.sleep_ms(10)
+            print("ota_data:{} count:{}".format(len(json_str),count))
+        self.read_ack_flag = 0
+        json_data = \
+        {
+            "event": "ota_end",
+        }
+        json_str  =ujson.dumps(json_data)
+        self.AI_uart.write(json_str)
+        
+        count =100
+        while True:
+            count -=1
+            if count <=0 or self.read_ack_flag == 1:
+                break
+            utime.sleep_ms(1)
+        self.bt_ota_flag = 0
 audio_buf = ['chaobingfatis', 'chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji']
 class AI_dev(Abstract):
     # AI
@@ -274,14 +609,21 @@ class AI_dev(Abstract):
             self.extint_AI = ExtInt(ExtInt.GPIO5,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
         else:
             self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
-            self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+            self.extint_AI = ExtInt(ExtInt.GPIO43,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
             #self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
             #蓝牙唤醒4G中断
-            self.extint_wakeup_cta1 = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.wakeup_extint_cb)
+            self.extint_wakeup_cta1 = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING, ExtInt.PULL_DISABLE, self.wakeup_extint_cb)
             #4G唤醒蓝牙中断
             self.PIN_wakeup_bt =Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_DISABLE, 0)
+            #蓝牙开电
+            self.PIN_BT_ON =Pin(Pin.GPIO31, Pin.OUT, Pin.PULL_DISABLE, 1)
+            #马达
+            self.PIN_MOT=Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_DISABLE, 1)
+            utime.sleep_ms(1000)
+            self.PIN_MOT=Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_DISABLE, 0)
+
         self.extint_wakeup_cta1_timer = osTimer()
-        self.extint_wakeup_cta1.enable()
+        # self.extint_wakeup_cta1.enable()
         self.extint_AI.enable()
         self.pwk_key_status = 0
         self.pwk_key_timer_count = 0
@@ -303,6 +645,10 @@ 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("wakeup_BT",self.wakeup_BT)
+        EventMesh.subscribe("sleep_BT",self.sleep_BT)
+        EventMesh.subscribe("sys_sleep_cb",self.sys_sleep_cb)
+        EventMesh.subscribe("GET_USB_STATE",self.get_usb_state)
         
         print("AI_dev:2")
         self.pk = PowerKey()
@@ -326,6 +672,15 @@ class AI_dev(Abstract):
         #EventMesh.publish("publish_AI_btnInfo",{"func":self.ntptime_cb})
         self.check_rest_timer_count = 0
         self.ai_uart = AI_UART()
+        self.ble_switch_flag_time = osTimer()
+        self.ble_switch_flag_time.start(5000, 0, self.ble_switch_flag_time_cb)
+    def ble_switch_flag_time_cb(self,*args):
+        ble_switch_flag =  EventMesh.publish("get_storage_config","switch_bt_state")#ble开关
+        if ble_switch_flag == None:
+            ble_switch_flag = 0
+        EventMesh.publish("send_ble_adv_switch_to_ble",str(ble_switch_flag))
+        EventMesh.publish("send_imei_to_ble")
+        pass
         print("AI_dev:end")
     def ntptime_cb(self):
         #ntptime.settime(8)
@@ -360,6 +715,8 @@ class AI_dev(Abstract):
                 EventMesh.publish("close_led")
                 EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"])
                 #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3')
+    def get_usb_state(self,event,msg):
+        return self.usb_status
     def btnInfo_queue_thread(self):
         while True:
             data = self.btnInfo_queue.get()
@@ -398,19 +755,61 @@ class AI_dev(Abstract):
             Power.powerRestart()
             EventMesh.publish("set_storage_config",["powerRestart",1])
         #print("publish_AI_btnInfo 2")
-    def powerKey_callback(self, status):
-        print("powerKey_callback:{}".format(status))
-    def wakeup_extint_cb(self,args):
+    
+    def sys_sleep_cb(self,event=None,msg=None):#休眠前回调
+        print("sys_sleep_cb!!!!!!!!!!!!!!!")
+        print("sys_sleep_cb!!!!!!!!!!!!!!!")
+        print("sys_sleep_cb!!!!!!!!!!!!!!!")
+        self.PIN_wakeup_bt.write(0)
+    def wakeup_BT(self,event=None,msg=None):#4G唤醒蓝牙
+        self.PIN_wakeup_bt.write(0)
+        count = 150
+        while(True):
+            count-=1
+            if count<=0:
+                return -1
+            if self.extint_wakeup_cta1.read_level() == 1:
+                self.PIN_wakeup_bt.write(1)
+                return 1
+            utime.sleep_ms(2)
+            if count%2 == 0:
+                self.PIN_wakeup_bt.write(0)
+            else:
+                self.PIN_wakeup_bt.write(1)
+
+        
+    def sleep_BT(self,event=None,msg=None):#使蓝牙休眠
+        print("sleep_BT!!!!!")
+        print("sleep_BT!!!!!")
+        print("sleep_BT!!!!!")
+        print("sleep_BT!!!!!")
+        self.PIN_wakeup_bt.write(0)
+        count = 300
+        while(True):
+            count-=1
+            if count<=0:
+                return -1
+            if self.extint_wakeup_cta1.read_level() == 0:
+                return 1
+            utime.sleep_ms(1)
+   
+   
+    def wakeup_extint_cb(self,args):#蓝牙唤醒4g
         print("wakeup_extint_cb:!!!!!!!!!")
+        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
         self.PIN_wakeup_bt.write(1)
         EventMesh.publish("publish_AI_btnInfo",{"func":self.extint_wakeup_cta1_cb})
     def extint_wakeup_cta1_cb(self):
-        self.extint_wakeup_cta1_timer.start(100, 1, self.extint_wakeup_cta1_timer_cb)
+        #self.extint_wakeup_cta1_timer.start(100, 1, self.extint_wakeup_cta1_timer_cb)
         pass
     def extint_wakeup_cta1_timer_cb(self, *args, **kwargs):
         if self.extint_wakeup_cta1.read_level() == 0:
             self.extint_wakeup_cta1_timer.stop()
-            self.PIN_wakeup_bt.write(0)
+            #self.PIN_wakeup_bt.write(0)
+
+    def powerKey_callback(self, status):
+        print("powerKey_callback:{}".format(status))
+   
 
     def pwk_extint_cb(self,args):#pwk
         try:
@@ -535,10 +934,12 @@ class AI_dev(Abstract):
     def AI_key_long_press(self):
         self.check_rest_timer_count = 0
         print("AI_key_long_press")
+        EventMesh.publish("wakeup_BT")
         EventMesh.publish("AI_key_long_press")
         
     def AI_key_release(self):
         print("AI_key_release")
+        
         EventMesh.publish("AI_key_release")
         
     def pwk_key_Long_Press(self,event=None,msg=None):
@@ -740,6 +1141,8 @@ class device_res_author(Abstract):
         # self.key = b"3LWfBicxfRZ3ZAqmZCFuvMdGUXdAFWkb" 
         # self.pid = "qLx4Pu4mSUQxyfVKGLXG"
         #7pin
+        # pid:YiMEGsAbHqYwhO3IRWVE
+        # 产品密钥:yFXqKI3EvznGbKLb4mxuW2SErG5XyJwZ
         self.key = b"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" 
         self.pid = "cqxJZi5CNgzjS3mX21Zw"
         # if dev_type == 'jswm' or dev_type == 'jswm_BOX':#金三完美
@@ -759,6 +1162,9 @@ 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("post_iccid_user", self.post_iccid_user)
+        self.post_iccidd_token_timer = osTimer()
+        self.post_iccidd_token_timer.start(10000, 0, self.post_iccidd_token_timer_cb)
         #EventMesh.publish_async("dev_NTP",thread_size = 8192)
 
         # count = 0
@@ -775,7 +1181,11 @@ class device_res_author(Abstract):
         self.dev_NTP()#获取时间
         self.dev_active() #设备激活
         self.dev_sign_in() #设备登入
+
+        self.connect_web_flag = 0
         print("device_res_author __init__ end !!!!!!!!!!!!!!!!!")
+    def post_iccidd_token_timer_cb(self,*argc):
+        EventMesh.publish("post_iccid_user")
 
     def get_dev_token(self, event, msg): 
         return self.dev_token
@@ -918,7 +1328,8 @@ 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.raisound.com/bz-api/dev/auth/active"
+                    url = "http://dmp.qipai.com.cn:30461/dev/auth/active"
+                    #url = "http://dmp.raisound.com/bz-api/dev/auth/active"
                 data =ujson.dumps(data)
                 response = None
                 response_result = 0
@@ -987,6 +1398,8 @@ class device_res_author(Abstract):
 
     #设备登入 没有Token 走登入获取token
     def dev_sign_in(self, event=None, msg=None):
+    
+
         signal = net.csqQueryPoll()
         if signal == -1 or self.get_sim_Status() != 1:#网络不正常
             print("dev_sign_in 无 SIM卡!!!!!!!!\r\n")
@@ -1028,7 +1441,8 @@ 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.raisound.com/bz-api/dev/auth/sign_in" #登入地址
+                    sign_url = "http://dmp.qipai.com.cn:30461/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
                 response = 0
@@ -1071,7 +1485,44 @@ class device_res_author(Abstract):
         except Exception as e:
                     print("post error!!!!!\r\n")
                     response_result = 0
+        if EventMesh.publish("get_dev_token") != None:
+            if len(EventMesh.publish("get_dev_token")) != 0:
+                if self.connect_web_flag == 0:
+                    EventMesh.publish("connect_iot_websocket_cb")
+                self.connect_web_flag = 1
         print("dev_sign_in end")
+            #ICCID上传
+    def post_iccid_user(self,event=None,msg=None):
+        response = None
+        try:
+            iccid = sim.getIccid()
+            if iccid != -1 and len(iccid) > 5:
+                print("pots_ICCID:{}".format(iccid))
+                #Headers = {'Transfer-Encodong':'chunked'}
+                token = EventMesh.publish("get_dev_token")
+                headers_T = None
+                if token:
+                    headers_T = {"qp-dt":"{}".format(token)}
+                #http://dmp.raisound.com/bz-api/dev/iccid?deviceId=866610001099679&iccid=89860002192307889057
+                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:
+                    url = "http://dmp.qipai.com.cn:30461/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid)
+                print("{} H:{}".format(url,headers_T))
+                response = request.post(url,headers = headers_T)
+                if response.status_code == 200:
+                    data = response.json()
+                    print("pots_ICCID:{}".format(data))
+                else:
+                    print("pots_ICCID  error!!!!")
+                    for i in response.text:
+                        print(i)
+                response.close()
+        except Exception as e:
+            usys.print_exception(e)
+            if response != None:
+                response.close()
     #获取新的令牌 更新token
     def update_dev_token(self, event=None, msg=None):
         print("update_dev_token")
@@ -1096,6 +1547,8 @@ class device_res_author(Abstract):
                 dev_tokenip = "http://dmp-global.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
             else:
                 dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
+                dev_tokenip = "http://dmp.qipai.com.cn:30461/dev/auth/token" #设备新令牌更新地址
+                
             token = self.dev_token
             if token == None:
                 token = ""
@@ -1125,6 +1578,9 @@ class device_res_author(Abstract):
         except Exception as e:
             usys.print_exception(e)   
         print("update_dev_token end")
+
+
+
         
 #OTA升级
 class OTA():
@@ -1326,7 +1782,10 @@ class AI_VC(Abstract):
             self.VC_mode = 0
         self.is_up_error= 0 #是否上传错误id
         self.Close_flag =0 #=1时,连续对话播放完音频就退出
+
+        self.play_new_voice_flag =0 #播放文字留言flag
         EventMesh.subscribe("play_tts",self.play_tts)
+        EventMesh.subscribe("play_new_voice",self.play_new_voice)
         self.AI_alarm = _ai_alarm.AI_alarm()
         self.error_data = []
         self.asr_taskid  = ""
@@ -1371,7 +1830,7 @@ class AI_VC(Abstract):
                 self.server_ip="118.145.158.207:22084"
             elif dev_type == "7PIN_BK" or dev_type == 'csh'or dev_type == "7PIN_BK_coze"or dev_type == 'momo':
                 #self.server_ip="amp.raisound.com"
-                self.server_ip="118.145.158.207:22086"
+                self.server_ip="dmp.qipai.com.cn:30746"#118.145.158.207:22086"
                 #self.server_ip="115.190.94.208:22080"
             elif dev_type == "7PIN_coze":
                 self.server_ip="118.145.158.207:22086"
@@ -1433,7 +1892,7 @@ class AI_VC(Abstract):
 
         self.VC_TTS_voice_type = EventMesh.publish("get_storage_config","VC_TTS_voice_type")#音色配置
         if self.VC_TTS_voice_type == None :
-            if dev_type == "G10" or  dev_type == "7PIN_BK"or dev_type == "szbst" :
+            if dev_type == "G10" or dev_type == "szbst" :#or  dev_type == "7PIN_BK":
                 self.VC_TTS_voice_type = {   
                                             "女":{
                                             "bot_name":"小瑞",
@@ -1978,12 +2437,13 @@ class AI_VC(Abstract):
         self.VC_record_state_flag = 0
         self.AI_key_long_press_flag = 0
         self.websocket_error_count = 0
-
+        self.AI_new_voice_url = "" #未读语音地址
         self.tts_in_data_len = 0
         self.tts_out_data_len = 0
         self.VC_satrt_flag = 0
         self.session_id = ""
         EventMesh.subscribe("AI_key_press", self.AI_key_press)
+        EventMesh.subscribe("stop_AI_record", self.stop_AI_record)
         EventMesh.subscribe("AI_key_release", self.AI_key_release)
         EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press)
         EventMesh.subscribe("pwk_key_release", self.pwk_key_release)
@@ -2176,6 +2636,7 @@ class AI_VC(Abstract):
             print('audio-play finish.!!!!!!')
 
     def AI_key_press(self, event, msg):#按键按下
+        EventMesh.publish("stop_voice_record") #开启静默需要关闭
         print("AI_key_press")
         self.get_config_timer_count = 0
         self.key_state = 1
@@ -2200,7 +2661,23 @@ class AI_VC(Abstract):
         # self.Close()
         # self.AI_VC_start()
         self.AI_key_long_press_flag = 0
-        
+    def stop_AI_record(self, event, msg):#停止AI对话
+        if self.VC_satrt_flag == 1:
+            self.get_config_timer_count = 0
+            self.AI_TTS_str = ""#"你好,有什么吩咐"
+            self.AI_ASR_str = ""
+            self.AI_ASR_str_tmp = ""
+            self.AI_key_long_press_flag = 0
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+            count = 0
+            while True:
+                if count >= 20 or self.VC_satrt_flag == 0:
+                    break
+                count+=1
+                utime.sleep_ms(500)
+
+       
 
     def AI_key_release(self, event, msg):#按键弹起
         print("AI_key_release123")
@@ -2242,6 +2719,7 @@ class AI_VC(Abstract):
     def pwk_key_release(self, event, msg):#电源键短按,关闭
         print("pwk_key_release")
         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+        EventMesh.publish("sleep_BT")#休眠蓝牙
 
     def key_prompt(self):
         EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
@@ -2372,6 +2850,7 @@ class AI_VC(Abstract):
                 usys.print_exception(e)
         self.VC_record_thread_id = 0
     #获取录音数据
+
     def VC_record_thread(self):
         ##return
         print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n")
@@ -2492,9 +2971,17 @@ class AI_VC(Abstract):
                             except Exception as e:
                                 usys.print_exception(e)
                             self.record_fd = open('/usr/record_data.pcm','w')
+                            self.record_fd_len = 0
                         if self.record_fd != None:
-                            self.record_fd.write(read_buf)
-                            print("write record:{}".format(len(read_buf)))
+                            try:
+                                self.record_fd.write(read_buf)
+                                print("write record:{}".format(len(read_buf)))
+                                self.record_fd_len = self.record_fd_len+len(read_buf)
+                                if self.record_fd_len >=300*1024:
+                                    EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                            except Exception as e:
+                                usys.print_exception(e)
+                                EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                             # count+=Record_len
                             # if count >150*1024:
                             #     self.record_fd.close()
@@ -2519,7 +3006,10 @@ class AI_VC(Abstract):
                     usys.print_exception(e)
                     #break
             self.VC_record_thread_lock = 0
-            utime.sleep_ms(100)
+            if self.record_data_save_flag == 1:
+                utime.sleep_ms(1)
+            else:
+                utime.sleep_ms(100)
         #fd.close()
         print("VC_record_thread:exit")
         self.VC_record_thread_id = 0#线程退出
@@ -2567,7 +3057,7 @@ class AI_VC(Abstract):
             req_str = "vc/chat?is_auth={}".format(self.is_auth)
             if dev_type == '7PIN_BK_coze' or dev_type == '7PIN_coze':
                 req_str = "vc/coze?is_auth={}".format(self.is_auth)
-            elif dev_type == 'jswm' or dev_type == 'jswm_BOX':
+            elif dev_type == 'jswm' or dev_type == 'jswm_BOX' :
                 req_str = "vc/agent?is_auth={}".format(self.is_auth)
 
             if(token):
@@ -2871,7 +3361,7 @@ class AI_VC(Abstract):
                             print("VC:Started!!!!!!!!\r\n")
                             if self.AI_TTS_str == "":
                                 #开始上传语音
-                                if dev_type != "7PIN" and dev_type != "7PIN_coze":
+                                if dev_type != "7PIN_coze":
                                     self.chenggong_tone()
                                 if self.VC_mode == 0    :
                                     self.VC_record_state_flag  =2
@@ -2881,6 +3371,10 @@ class AI_VC(Abstract):
                                 
                             else:
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                            
+                            if self.AI_new_voice_url != "":
+                                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})
+
                             self.VC_state =  VC_State_None  
                         elif jsload_data["event"] == "config.update" :#配置更新中,需要停止录音
                             self.VC_state = VC_State_End
@@ -2919,10 +3413,12 @@ class AI_VC(Abstract):
                                     pass    
                             #self.VC_Speech_End()
                             #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-                            if self.record_data_save_flag == 1:
-                                if self.record_fd :
-                                    self.record_fd.close()
-                                self.record_fd = None
+
+                            # if self.record_data_save_flag == 1:
+                            #     if self.record_fd :
+                            #         self.record_fd.close()
+                            #     self.record_fd = None
+
                             # if dev_type != "7PIN" :
                             #EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone}) 
                         elif jsload_data["event"] == "vad.silence" :#VAD 终止的标识 
@@ -2999,6 +3495,21 @@ class AI_VC(Abstract):
                             else:
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":jsload_data["payload"]["message"]}) 
                             pass
+                            if self.play_new_voice_flag == 1:
+                                self.play_new_voice_flag=0
+                                EventMesh.publish("update_play_new_voice_info")
+                                EventMesh.publish("play_new_voice_list")
+                                pass
+
+                        elif jsload_data["event"] == "audio.convert.completed":#接口
+                            if self.play_new_voice_flag == 1:
+                                self.play_new_voice_flag=0
+                                EventMesh.publish("update_play_new_voice_info")
+                                EventMesh.publish("play_new_voice_list")
+                                
+                                pass
+                            pass
+                        
                     else:#下发音频数据
                         #self.AI_ASR_str = ""#下发音频后清掉asr结果
                         
@@ -3327,6 +3838,16 @@ class AI_VC(Abstract):
                             return 1
                     except Exception as e:
                         usys.print_exception(e)
+                if text.find("取消闹钟") != -1: #清空所有闹钟
+                    try:
+                        self.AI_TTS_str = EventMesh.publish("AI_delete_alarm")
+                    except Exception as e:
+                        usys.print_exception(e)
+                    return 0
+                if text.find("闹钟列表") != -1 :
+                    EventMesh.publish("read_alarm_list")
+                    return 0
+
         except Exception as e:
                 usys.print_exception(e)
         self.AI_TTS_str  = cmd["command"]["fail_prompt"]
@@ -3580,10 +4101,12 @@ class AI_VC(Abstract):
                         return 0
                     else:
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                        EventMesh.publish("sleep_BT")#休眠蓝牙
                         return 1
                 if len(text)<12 and (text.find("关机") != -1 ):
                     if dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                        EventMesh.publish("sleep_BT")#休眠蓝牙
                         return 1
                     EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                     EventMesh.publish("Power_off")
@@ -3693,6 +4216,7 @@ class AI_VC(Abstract):
                 self.ud_error(["VC",self.VC_taskid])
             else:
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                EventMesh.publish("sleep_BT")#休眠蓝牙
         
         # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag))
         if self.LocalRespondingEnded_timerout>0  :#
@@ -3702,11 +4226,13 @@ class AI_VC(Abstract):
                 self.LocalRespondingEnded_timerout = 0
                 if self.VC_mode == 1 :#长按单次问答模式
                     EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                    EventMesh.publish("sleep_BT")#休眠蓝牙
                 else:
                     EventMesh.publish("open_led_blue")
                     if self.Close_flag == 1:
                         self.Close_flag = 0
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                        EventMesh.publish("sleep_BT")#休眠蓝牙
                     else:
                         #utime.sleep_ms(1000)
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End})
@@ -3741,6 +4267,7 @@ class AI_VC(Abstract):
         if self.VC_Thinking_timerout < 100:
             self.VC_Thinking_timerout = 0
         EventMesh.publish("open_led_all")
+        EventMesh.publish("wakeup_BT")
         self.VC_Play_End()#关闭音频播放
         print("AI_VC_start2")
         #self.aud.aud_tone_play(16,200)#播放按键音
@@ -3882,8 +4409,9 @@ class AI_VC(Abstract):
         json_data["payload"]["outbound_attributes"]["provider"]=self.outbound_attributess_provider#TTS音色服务选择,火山
         json_data["payload"]["inbound_attributes"]["provider"]=self.inbound_attributess_provider#ASR服务选择,火山
         if dev_type == "7PIN_BK"or dev_type == "7PIN_BK_coze"or dev_type == "G10":#小瑞
-            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7462617881076351002"#语言助手
-            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7462621757327196187"
+            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7518964489061072911"#语言助手
+            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7518975730094243894"
+            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["use_workflow"]=True
             # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7486697248416989193"#极简
             # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7486698347416649778"
             #json_data["payload"]["dialog_attributes"]["provider"]="doubao"#豆包
@@ -3987,6 +4515,25 @@ class AI_VC(Abstract):
         
         
         self.VC_state =  VC_State_SpeechStart
+    #开始未读语音消息
+    def AI_client_VC_send_speech(self,url):
+        json_data = \
+        {
+            "event": "audio.convert",
+            "payload": {
+                "audio_convert_request": {
+                    "audio_url": url,
+                    "bit_depth": 16,
+                    "channels": 1,
+                    "sample_rate": 16000,
+                    "target_format": "pcm"
+                }
+            }
+        }
+        self.websocket_deconnect_VC()
+        self.AI_audio_queue_thread_close()
+        self.AI_VC_start() 
+        self.AI_client_VC_send(ujson.dumps(json_data))
     #结束上传语音
     def AI_client_VC_end_speech(self):
         json_data = \
@@ -4030,6 +4577,48 @@ 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 play_new_voice(self,event = None,msg= None):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.play_new_voice_cb,"data":msg}) 
+    def play_new_voice_cb(self,data):
+        try:
+            new_voice_url = data[0] #音频地址
+            is_close_VC = data[1]
+            if new_voice_url != "":
+                self.AI_new_voice_url = new_voice_url
+            if is_close_VC != None:
+                self.Close_flag = is_close_VC
+            if self.AI_VC_send_data_queue.empty()!=True:
+                self.AI_VC_send_data_queue.clear()
+            if self.AI_ASR_send_data_queue.empty()!=True:
+                self.AI_ASR_send_data_queue.clear()
+            EventMesh.publish("open_led_all")
+            self.AI_ASR_send_buf_len = 0
+            self.VC_Speech_End()
+            self.websocket_deconnect_VC()
+            self.AI_VC_start()
+            self.play_new_voice_flag = 1
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC}) 
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        except Exception as e:
+                usys.print_exception(e)   
+        pass
+    def AI_client_new_voice(self): #上传未读的语音地址
+        json_data = \
+        {
+            "event": "audio.convert",
+            "payload": {
+                "audio_convert_request": {
+                    "audio_url": self.AI_new_voice_url,
+                    "bit_depth": 16,
+                    "channels": 1,
+                    "sample_rate": 16000,
+                    "target_format": "pcm"
+                }
+            }
+        }
+        print("AI_client_new_voice!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{}".format(json_data))
+        self.AI_client_VC_send(ujson.dumps(json_data))
     
     def chenggong_tone(self):
         EventMesh.publish("audio_montage_play",["chenggong.mp3"])    
@@ -4161,7 +4750,7 @@ class AI_VC(Abstract):
 
     def Close(self):
         self.VC_Thinking_timerout = 0
-        self.VC_satrt_flag = 0
+        
         self.AI_TTS_str = ""
         self.AI_ASR_str = ""
         self.AI_ASR_str_tmp = ""
@@ -4224,6 +4813,7 @@ class AI_VC(Abstract):
         self.AI_ASR_send_buf_len = 0
         #self.AI_WS_connect_Queue.put(self.AI_client_VC)
         EventMesh.publish("close_led")
+        self.VC_satrt_flag = 0
         # try:
         #     while True:
         #         if self.AI_WS_connect_Queue.empty()!=True:
index 5085bac..44d5cff 100644 (file)
@@ -4,9 +4,10 @@ import usys
 import ujson
 import osTimer
 import utime
+import request
 class AI_alarm():
     """
-    sjon格式{
+    """""" {
     "alarm_type":"间隔闹钟", #闹钟类型。示例值:间隔闹钟(喝水提醒,重复每天闹钟)、单次闹钟(会议提醒)
     "alarm_timestamp":1750402089,#单次闹钟触发时间戳,单位:秒。只有单次闹钟有效
     "repeat_day":["周一","周二","周三","2025-06-20"],#按天循环规则。示例值:周一,周五,每天,2025-06-20(自定义日期)
@@ -15,198 +16,880 @@ class AI_alarm():
     "alarm_timer":"06:50",#触发时间。示例值:06:50 ,6点50分时触发闹钟
     "alarm_content":"周例会",#闹钟提醒内容。为空时,播放本地默认音频,不为空时,tts循环播放内容。示例值:"喝水提醒"
     }
+    sjon格式{
+    {
+            "name":"闹钟名称",
+            "loop":"0101001",
+            "state":"0/1 0表示关闭,1表示开启",
+            "time":"14:34",
+            "ringTimes":1/2/3,
+            "alarmMode":"ring表示响铃,shake表示震动,both表示都执行",
+            "shakeType":"short表示短震动,long表示长震动,none表示不震动",
+            "ringUrl":"铃声地址,空为默认地址",
+            "index":索引,0~9,最多 10个闹钟,删除闹钟重新排序
+        }
+    }
     """
+    #最多只能设置五个闹钟
     def __init__(self):
-        self.alarm_array = EventMesh.publish("get_storage_config","alarm_array")#读取闹钟数组
-        if self.alarm_array ==None:
+        self.alarm_save_max_count = 5
+        self.alarm_array = EventMesh.publish("get_storage_config","alarm_list")#读取闹钟数组
+        if self.alarm_array is None:
+            self.alarm_array =[]
+        else:
             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 or len(self.alarm_array) == 0:
+            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 = [] #闹钟重复判断标志列表
+        self.is_alarm = 0
+        self.minute_now_old = 0
+        self.old_minute = 0
+        self.record_start_min = 0
+
         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)
+        EventMesh.subscribe("AI_alarm_start",self.AI_alarm_start) 
+        EventMesh.subscribe("GET_NEED_ALARM_REPORT_INFO",self.get_need_alarm_report_info)#读取闹钟数组
+    def alarm_get_statu(self,event=None,msg=None):
+        print("alarm_get_statu = {}".format(self.alarm_timer_sta))
+        return self.alarm_timer_sta
+    def all_states_zero(self,lst):
 
+        """检查列表中所有字典的state是否全为0"""
+        for item in lst:
+            # 检查是否存在state键且其值严格等于0(数字类型)
+            if 'state' not in item or item['state'] != 0:
+                return False
+        return True
     def AI_alarm_open(self,event=None,msg=None):
+        print("AI_alarm_open")
+        if len(self.alarm_array) == 0:
+            return
+        self.alarm_timer_sta = 1
         self.AI_alarm_timer.start(20000, 1, self.AI_alarm_timer_cb)
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_alarm_poll}) 
 
     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_list")#读取闹钟数组
+        if self.alarm_array ==None:
+            return 0
+        else:
+            return 1
     def AI_alarm_poll(self):#轮询调用
-        is_alarm = 0 #是否触发闹钟
-        alarm_TTS_str =""#闹钟播放tts字符串
+        pass
+
+    def AI_alarm_start(self,event,msg):#轮询调用
+       
+        
+        alarm_TTS_str ={}#闹钟播放tts字符串
         repeat_day_flag = 0
         alarm_timer_flag = 0
-        if len(self.alarm_array)>0:
+        aIndex = 0
+        loop_ring = 0
+        # print("AI_alarm_poll111")
+        if len(self.alarm_array) == 0:
+            return
+        # print("self.alarm_array = {}".format(self.alarm_array))
+        time_tuple = utime.localtime()#获取当前日期&时间的元组 
+        minute_now = time_tuple[4]
+        if len(self.alarm_array) > 0:
+            self.minute_now_old = minute_now
+            # print("AI_alarm_poll222")
+            if self.all_states_zero(self.alarm_array) == True:
+                print("_alarm:errror!!!!!!")
+                return
             try:
                 now_time = utime.localtime()
-                for _alarm in self.alarm_array :
-                    if _alarm["alarm_type"] == "重复":
-                        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 self.is_alarm == 1: #正在响铃不需要检查
+                    if now_time[4] != self.old_minute: #下一个一分钟再次检查
+                        self.old_minute = now_time[4]
+                        return
+                self.old_minute = now_time[4]
+                self.is_alarm = 0
+                # "name":"闹钟名称",
+                # "loop":"0101001",
+                # "state":"0/1 0表示关闭,1表示开启",
+                # "time":"14:34",
+                # "ringTimes":1/2/3,
+                # "alarmMode":"ring表示响铃,shake表示震动,both表示都执行",
+                # "shakeType":"short表示短震动,long表示长震动,none表示不震动",
+                # "ringUrl":"铃声地址,空为默认地址",
+                # "single":1 有该字段表示单次闹钟 末年末月提醒 date还需要加这个字段 2025-09-09
+                # "interval":当前字段表示间隔多久提醒  valid_time还需要加这个字段 9:00-10:00
+                # "index":索引,0~9,最多 10个闹钟,删除闹钟重新排序
+                for i,_alarm in enumerate(self.alarm_array):
+                    self.is_alarm = 0
+                    loop_ring = 0
+                    alarm_TTS_str ={}
+                    state = int(_alarm["state"])  #字符0转int
+                    # print("_alarm:{}".format(_alarm))
+                    if state == 0:
+                        continue
+                    time_tuple = utime.localtime()#获取当前日期&时间的元组
+                    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 "single" in _alarm:  #单次闹钟
+                        set_year = 1970
+                        set_month = 1
+                        set_day = 1
+                        set_hour= 0
+                        set_min = 0
 
+                        if "date" in _alarm:
+                            set_year=int(_alarm["date"].split("-")[0])
+                            set_month=int(_alarm["date"].split("-")[1])
+                            set_day=int(_alarm["date"].split("-")[2])
+
+                            set_hour=int((_alarm["time"].split(":"))[0])
+                            set_min=int((_alarm["time"].split(":"))[1])
+                            if year_now == set_year and month_now == set_month and day_now == set_day and hour_now == set_hour and minute_now == set_min:
+                                print("single alarm!!!!!!!!!!!!!!")
+                                loop_ring =1
+                                self.is_alarm=1
+                                alarm_TTS_str = _alarm
+                                aIndex = i
+                                break #该提醒了
+                        continue
+                    elif "interval" in _alarm: #间隔喝水提醒
+                        # H_H = valid_time.split("-") #9:00-10:00
+                        # start_time = H_H[0].split(":")
+                        # end_time = H_H[1].split(":")
+                        interval_time = _alarm["valid_time"].split("-")
+                        start_time = interval_time[0].split(":")
+                        start_time[0] = int(start_time[0])
+                        start_time[1] = int(start_time[1])
+                        end_time = interval_time[1].split(":")
+                        end_time[0] = int(end_time[0])
+                        end_time[1] = int(end_time[1])
+                        week_now = (time_tuple[6])+1 #保证从1-7 
+                        loop = _alarm["loop"]
+                        week_list=[]
+                        for n,we in enumerate(loop): #日 一 二 三 四 五 六 0-6
+                            if we == "1":
+                                week = n
+                                if n == 0:
+                                    week = 7 #星期天 后面就是按照一 二 三 四 五 六
+                                week_list.append(week) #6-0  6-1 -6-2 6-3 6-4 6-5 6-6
+                        
+                        # print("week_list:{} week_now:{}".format(week_list,week_now))
+                        #9:00 - 12:00
+                        #587-
+                        if len(_alarm["date"]) != 0 and week_list == []:
+                            set_year = int(_alarm["date"].split("-")[0])
+                            set_month = int(_alarm["date"].split("-")[1])
+                            set_day = int(_alarm["date"].split("-")[2])
+                            #c = 2025
+                            #s = 2024
+                            #当前年大于设置年 时间过了
+                            #年相等 当前月大于设置月 时间已过
+                            #年月相等 当前日大于设置日 时间已过
+                            #年月日相等 当前时间大于设置结束时间
+                            if year_now > set_year or (year_now == set_year and month_now > set_month) or \
+                                (year_now == set_year and month_now == set_month and day_now > set_day) or \
+                                (year_now == set_year and month_now == set_month and day_now == set_day and hour_now*60+minute_now > end_time[0]*60+end_time[1]): #只要当前年份大于设置就关闭不需要提醒
+
+                                self.alarm_array[i]["state"] = "0"
+                                print("时间日期过了{}".format(_alarm))
+                                EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
+                                continue  #不执行下面条件判断
+                        if hour_now*60+minute_now >= start_time[0]*60+start_time[1] and hour_now*60+minute_now <= end_time[0]*60+end_time[1]:
+                            current_time = hour_now*60+minute_now #9:00 541 >= start_time[0]*60+start_time[1]+
+                            interval = current_time-(start_time[0]*60+start_time[1]) #9
+                            repeat_min =  _alarm["repeat_min"] #间隔提醒时间分钟
+                            if self.record_start_min == 0:
+                                self.record_start_min = current_time #9:00 需要转换成分钟数
                             
-                            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
-                            
-                    elif _alarm["alarm_type"] == "单次":
-                        alarm_timer = _alarm["alarm_timer"]
-                        H_M = alarm_timer.split(':')
-                        if len(H_M) != 2:
-                            continue
-                        repeat_day = _alarm["repeat_day"]
-                        #print("repeat_day:{}".format(repeat_day[0]))
-                        Y_M_D = repeat_day[0].split('-')
-                        #print("Y_M_D:{}".format(Y_M_D))
-                        if len(Y_M_D)<3:
+                            #当前时间分钟数据减去上一次保存的时间分钟数据 大于设定的间隔时间就开始提醒用户
+                            if current_time - self.record_start_min >= repeat_min and repeat_min > 0 and self.alarm_min_repeat_tmp != minute_now:
+                                self.record_start_min = current_time #记录下一个开始的时间点 加间隔时间就是下一次需要提醒的时间点
+                                self.alarm_min_repeat_tmp = minute_now
+                                set_year = 0
+                                set_month = 0
+                                set_day = 0
+                                if len(_alarm["date"]) != 0:
+                                    set_year = int(_alarm["date"].split("-")[0])
+                                    set_month = int(_alarm["date"].split("-")[1])
+                                    set_day = int(_alarm["date"].split("-")[2])
+                                    pass
+
+                                if (all(c == '0' for c in loop) == 1 and year_now == set_year and month_now == set_month and day_now == set_day) or \
+                                (all(c == '0' for c in loop) == 0 and (week_now in week_list)):
+                                    self.is_alarm=1
+                                    alarm_TTS_str = _alarm
+                                    aIndex = i
+                                    break   
+                        continue
+                    #重复闹钟不要修改
+                    set_hour = int((_alarm["time"].split(":"))[0])
+                    set_min = int((_alarm["time"].split(":"))[1])
+                
+                    week_now = (time_tuple[6])+1 #保证从1-7 
+                    loop = _alarm["loop"]
+                    week_list=[]
+                    for n,we in enumerate(loop): #日 一 二 三 四 五 六 0-6
+                        if we == "1":
+                            week = n
+                            if n == 0:
+                                week = 7 #星期天 后面就是按照一 二 三 四 五 六
+                            week_list.append(week) #6-0  6-1 -6-2 6-3 6-4 6-5 6-6
+                    
+                    # print("week_list is interval single:{} week_now:{}".format(week_list,week_now))
+                    if week_list == []: #0000000 9:00
+                        if  hour_now*60+ minute_now > set_hour *60 + set_min: #时间过了不需要提醒
+                            self.alarm_array[i]["state"] = "0"
+                            print("单次闹钟时间过了{}".format(self.alarm_array))
+                            EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
                             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
-                                continue
-                        #ret_str += "{},{}点{}分提醒您:{}。".format(_alarm["repeat_day"],H_M[0],H_M[1],_alarm["alarm_content"])
-                if  is_alarm == 1 :
-                    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 (week_now in week_list) or all(c == '0' for c in loop) == 1:
+                        if set_hour *60 + set_min == hour_now*60+ minute_now and self.alarm_min_repeat_tmp != minute_now:
+                            self.alarm_min_repeat_tmp = minute_now
+                            if all(c == '0' for c in loop) == 1:
+                                loop_ring =1
+                            self.is_alarm=1
+                            alarm_TTS_str = _alarm
+                            aIndex = i
+                            break
+                        continue
+                
+                    
+                #     "name":"闹钟名称",
+                # "loop":"0101001",
+                # "state":"0/1 0表示关闭,1表示开启",
+                # "time":"14:34",
+                # "ringTimes":1/2/3,
+                # "alarmMode":"ring表示响铃,shake表示震动,both表示都执行",
+                # "shakeType":"short表示短震动,long表示长震动,none表示不震动",
+                # "ringUrl":"铃声地址,空为默认地址",
+                # "index":索引,0~9,最多 10个闹钟,删除闹钟重新排序
+                if self.is_alarm == 1:
+                    if loop_ring == 1: #单次闹钟
+                        print("aIndex:{} alarm_array[aIndex]:{}".format(aIndex,self.alarm_array[aIndex]["state"]))
+                        self.alarm_array[aIndex]["state"] = "0"
+                        print("aIndex{}".format(self.alarm_array))
+                        EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
+
+                    name = alarm_TTS_str["name"]
+                    AringTimes  = alarm_TTS_str["ringTimes"]
+                    alarmMode = alarm_TTS_str["alarmMode"]
+                    shakeType = alarm_TTS_str["shakeType"]
+                    print("{} {} {}".format(AringTimes,alarmMode,shakeType))
+                    if alarmMode == "ring": #只响铃
+                        tts_audio = "chenggong.mp3"
+                        if AringTimes == 0:
+                            AringTimes = 1
+                        tts_str = [tts_audio] * AringTimes
+                        print(tts_str)
+                        # EventMesh.publish("audio_montage_play",tts_str) 
+                        pass
+                    elif alarmMode == "shake": #只振动
+                        if shakeType == "short":
+                            EventMesh.publish("set_motor_time",[1,1,5,8,4])#设置马达参数
+                            pass
+                        elif shakeType == "long":
+                            EventMesh.publish("set_motor_time",[1,1,5*2*2,8,4])#设置马达参数
+                            pass 
+                    elif alarmMode == "both": #响铃加振动
+                        tts_audio = "chenggong.mp3"
+                        if AringTimes == 0:
+                            AringTimes = 1
+                        tts_str = [tts_audio] * AringTimes
+
+                        # EventMesh.publish("audio_montage_play",tts_str) 
+                        if shakeType == "short":
+                            EventMesh.publish("set_motor_time",[1,1,5,8,4])#设置马达参数
+                            pass
+                        elif shakeType == "long":
+                            EventMesh.publish("set_motor_time",[1,1,5*2*2,8,4])#设置马达参数
+                        
+                        # EventMesh.publish("audio_montage_play",["chenggong.mp3"]) 
+                        pass
+                    base_sentence = "{}".format(name)
+                    if AringTimes == 0:
+                        AringTimes = 1
+                    repeat_sentence = (base_sentence + ",") * AringTimes  # 重复5次并加逗号分隔
+                    final_sentence = repeat_sentence.rstrip(",")
+                    
+                    EventMesh.publish("play_tts",[final_sentence,1])  #播放tts闹钟文本内容
+
             except Exception as e:
                 usys.print_exception(e)
                 pass
 
+
     def AI_alarm_poll_extern(self,event=None,msg=None):#外部调用轮询间隔,关闭定时器调用
-        self.AI_alarm_timer.stop()
+        self.AI_alarm_timer.start(1000, 1, self.AI_alarm_timer_cb)
         EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_alarm_poll}) 
 
+    #params_json:
+    # {"alarm": 
+    # [
+    # {
+    # "alarm_content": "吃药", 
+    # "alarm_timer": "9:00", 
+    # "alarm_type": "", 
+    # "repeat_day": ["周一","周二","周三","周三","周四"], 
+    # "repeat_min": 0, #间隔多久提醒一次
+    # "valid_time": ""} #只有间隔循环闹钟才生效 9:00-12:00
+    # ], 
+    # "is_righ, "is_right": false}
     def AI_add_alarm(self,event=None,alarm_array_u=None):#添加闹钟数组
-        ret = 0
+        if len(alarm_array_u) > 1 or len(alarm_array_u) == 0:
+            print("AI_add_alarm: > 1")
+            return [-1]
+        count = 0
+        week_str = ["周日","周一","周二","周三","周四","周五","周六"]
         alarm_array_tmp = self.alarm_array
+        if alarm_array_tmp is None:
+            alarm_array_tmp =[]
+        
+        # if len(self.alarm_array) >= self.alarm_save_max_count : #最多五个普通闹钟
+        #    tts =  "闹钟列表已满,请清除闹钟后再设置"
+        #    return [1,tts]
         #已添加闹钟1,周一,周二,周三,6:50分提醒您周例会
         ret_str = "已添加"
         print("AI_add_alarm:{}".format(alarm_array_u))
+        # "name":"闹钟名称",
+        # "loop":"0101001",
+        # "state":"0/1 0表示关闭,1表示开启",
+        # "time":"14:34",
+        # "ringTimes":1/2/3,
+        # "alarmMode":"ring表示响铃,shake表示震动,both表示都执行",
+        # "shakeType":"short表示短震动,long表示长震动,none表示不震动",
+        # "ringUrl":"铃声地址,空为默认地址",
+        # "single":1 有该字段表示单次闹钟 末年末月提醒 date还需要加这个字段 2025-09-09
+        # "interval":当前字段表示间隔多久提醒  valid_time还需要加这个字段 9:00-10:00
+        # "index":索引,0~9,最多 10个闹钟,删除闹钟重新排序
+
+
         try:
+            get_alarm_count = len(self.alarm_array)
+            count = 0
+            if len(alarm_array_u) != 0:
+                count = get_alarm_count
+           
+            save_alarm_tmp = []
             for _alarm in alarm_array_u :
-                if ("alarm_content" in _alarm )and (_alarm["alarm_type" ] == "重复" or _alarm["alarm_type" ] == "单次" ):#简单的判断这个配置是合法的
-
-                    ret +=1  
-                    alarm_array_tmp.append(_alarm)
-                    ret_str += "闹钟{},".format(len(alarm_array_tmp))
-                    
-                    
-                    if _alarm["alarm_type"] == "重复":
-                        
-                        if _alarm["repeat_min"] ==0: #每天只提醒一次,已添加闹钟1,周一,周二,周三,6:50分提醒您周例会
-                            alarm_timer = _alarm["alarm_timer"]
-                            H_M = alarm_timer.split(':')
-                            if len(H_M) != 2:
+                
+                if ("alarm_content" in _alarm )and (_alarm["alarm_type"] == "重复" or _alarm["alarm_type" ] == "单次" or ("repeat_min" in _alarm )):#简单的判断这个配置是合法的
+                    # #判断闹钟数字合法
+                    alarm_tmp = {}
+                    need_alarm_info = ""
+                    if _alarm["repeat_min"] == 0: #闹钟每天提醒一次 不是间隔时间提醒
+                        if _alarm["alarm_type"] == "重复": #
+                            if len(_alarm["alarm_timer"]) == 0:
                                 return [-1]
-                            ret_str += "{},{}点{}分提醒您{}。".format(_alarm["repeat_day"],H_M[0],H_M[1],_alarm["alarm_content"])
-                        else:#每天循环间提醒。已添加闹钟1,周一,周二,周三,9点到18点每隔60分钟提醒您喝水
-                            valid_time = _alarm["valid_time"]
-                            H_H = valid_time.split('-')
-                            if len(H_H) != 2:
-                                return [-1]
-                            start_time = H_H[0].split(':')
-                            end_time = H_H[1].split(':')
-                            if len(start_time)<2 or len(end_time)<2:
+                            repeat_day=_alarm["repeat_day"]
+                            alarm_timer=_alarm["alarm_timer"]
+                            alarm_content=_alarm["alarm_content"]
+                            if len(alarm_content) == 0:
+                                alarm_content = "小瑞提醒您了"
+                            if len(alarm_timer) == 0:
+                                alarm_timer = "00:00"
+                            if len(alarm_timer) > 5:
+                                alarm_timer=str(alarm_timer.split(":")[0])+":"+str(alarm_timer.split(":")[1])
+                                pass
+                            loop = "0000000"
+                            loop_list = list(loop)
+                            tts_week = ""
+                            for i,week in enumerate(repeat_day):
+                                tts_week+=week+','
+                                if week == "周日":
+                                    loop_list[0]="1" 
+                                elif week == "周一":
+                                    loop_list[1]="1" 
+                                elif week == "周二":
+                                    loop_list[2]="1" 
+                                elif week == "周三":
+                                    loop_list[3]="1" 
+                                elif week == "周四":
+                                    loop_list[4]="1" 
+                                elif week == "周五":
+                                    loop_list[5]="1" 
+                                elif week == "周六":
+                                    loop_list[6]="1" 
+                                    
+                            tts_hour = int((alarm_timer.split(":"))[0])
+                            tts_min = int((alarm_timer.split(":"))[1])
+                            loop = "".join(loop_list)
+                            print("loop normber:{}".format(loop))
+                            alarm_tmp["name"]=alarm_content
+                            alarm_tmp["loop"]=loop
+                            alarm_tmp["state"]="1"
+                            alarm_tmp["time"]=alarm_timer
+                            alarm_tmp["ringTimes"]=1
+                            alarm_tmp["alarmMode"]="ring"
+                            alarm_tmp["shakeType"]="none"
+                            save_alarm_tmp.append(alarm_tmp)
+                            #已添加闹钟2 周一 周二 周三,周四 
+                            count+=1
+                            print("count:{}".format(count))
+                            need_alarm_info = "闹钟{},".format(count)
+                            if len(_alarm["alarm_content"]) != 0:
+                                need_alarm_info += "{}{}点{}分 提醒您该{}".format(tts_week,tts_hour,tts_min,alarm_content)
+                            else:
+                                need_alarm_info += "{}{}点{}分 {}".format(tts_week,tts_hour,tts_min,alarm_content)
+                            pass
+                            break
+                        elif _alarm["alarm_type"] == "单次": #
+                            if len(_alarm["alarm_timer"]) == 0:
                                 return [-1]
-                            ret_str += "{},{}点{}分到{}点{}分,每隔{}分钟提醒您{}。".format(_alarm["repeat_day"],
-                                                                              start_time[0],start_time[1],end_time[0],end_time[1],
-                                                                              _alarm["repeat_min"],_alarm["alarm_content"])
-                    elif _alarm["alarm_type"] == "单次":
-                        alarm_timer = _alarm["alarm_timer"]
-                        H_M = alarm_timer.split(':')
-                        if len(H_M) != 2:
+                            #{"alarm": [
+                            # {"alarm_content": "", 
+                            # "alarm_timer": "14:41", 
+                            # "alarm_type": "", 
+                            # "repeat_day": ["2025-08-06"],
+                            #  "repeat_min": 0, "valid_time": ""}
+                            # ], 
+                            # "is_right": false}
+
+                            repeat_day=_alarm["repeat_day"][0]
+                            date_year = int(repeat_day.split("-")[0])
+                            date_month = int(repeat_day.split("-")[1])
+                            date_day = int(repeat_day.split("-")[2])
+                            alarm_timer = _alarm["alarm_timer"]
+                            alarm_content=_alarm["alarm_content"]
+                            if len(alarm_content) == 0:
+                                alarm_content = "小瑞提醒您了"
+                            if len(alarm_timer) == 0:
+                                alarm_timer = "00:00"
+                            if len(alarm_timer) > 5:
+                                alarm_timer=str(alarm_timer.split(":")[0])+":"+str(alarm_timer.split(":")[1])
+                                pass
+                            loop = "0000000"
+                            tts_hour = int((alarm_timer.split(":"))[0])
+                            tts_min = int((alarm_timer.split(":"))[1])
+                            print("loop single:{}".format(loop))
+                            alarm_tmp["name"]=alarm_content
+                            alarm_tmp["loop"]=loop #不需要判断星期是否符合条件
+                            alarm_tmp["state"]="1"
+                            alarm_tmp["time"]=alarm_timer
+                            alarm_tmp["ringTimes"]=1
+                            alarm_tmp["alarmMode"]="ring"
+                            alarm_tmp["shakeType"]="none"
+                            alarm_tmp["single"]=1
+                            alarm_tmp["date"]=repeat_day #单次提醒的年月日
+                            save_alarm_tmp.append(alarm_tmp)
+                            count+=1
+                            print("count:{}".format(count))
+                            need_alarm_info = "闹钟{},".format(count)
+                            if len(_alarm["alarm_content"]) != 0:
+                                need_alarm_info+= "{}年{}月{}日,{}点{}分 提醒您该{}".format(date_year,date_month,date_day,tts_hour,tts_min,alarm_content)
+                            else:
+                               need_alarm_info+= "{}年{}月{}日,{}点{}分,{}".format(date_year,date_month,date_day,tts_hour,tts_min,alarm_content)
+                            pass
+                            break
+                        
+                    else:
+                        #{"alarm": [
+                        # {"alarm_content": "", 
+                        # "alarm_timer": "", 
+                        # "alarm_type": "", 
+                        # "repeat_day": ["周一","周二","周三"] []
+                        #  "repeat_min": 0, "valid_time": "9:0-10:0"}
+                        # ], 
+                        # "is_right": false}
+                        if ("valid_time" in _alarm) == 0:
                             return [-1]
-                        repeat_day = _alarm["repeat_day"]
-                        print("repeat_day:{}".format(repeat_day[0]))
-                        Y_M_D = repeat_day[0].split('-')
-                        print("Y_M_D:{}".format(Y_M_D))
-                        if len(Y_M_D)<3:
+                        if _alarm["valid_time"].find("-") == 0:
                             return [-1]
-                        ret_str += "{}年{}月{}日,{}点{}分提醒您:{}。".format(Y_M_D[0],Y_M_D[1],Y_M_D[2],H_M[0],H_M[1],_alarm["alarm_content"])
+                        time_tuple = utime.localtime()#获取当前日期&时间的元组
+                        year_now = time_tuple[0]
+                        month_now = time_tuple[1]
+                        day_now = time_tuple[2]
+                        loop = "0000000"
+                        repeat_day = _alarm["repeat_day"]
+                        repeat_min = _alarm["repeat_min"]
+                        
+                        tts_week = ""
+                        loop_list=list(loop)
+                        if repeat_day == []: #仅今天提醒
+                            alarm_tmp["date"] = "{}-{}-{}".format(int(year_now),int(month_now),int(day_now))
+                            pass
+                        else:
+                            elements_with_dash = [item for item in repeat_day if "-" in item] #具体的时间
+                            if len(elements_with_dash) > 0:
+                                alarm_tmp["date"] = elements_with_dash[0]
+                                
+                            else:
+                                for i,week in enumerate(repeat_day):
+                                    tts_week+=week+','
+                                    if week == "周日":
+                                        loop_list[0]="1" 
+                                    elif week == "周一":
+                                        loop_list[1]="1" 
+                                    elif week == "周二":
+                                        loop_list[2]="1" 
+                                    elif week == "周三":
+                                        loop_list[3]="1" 
+                                    elif week == "周四":
+                                        loop_list[4]="1" 
+                                    elif week == "周五":
+                                        loop_list[5]="1" 
+                                    elif week == "周六":
+                                        loop_list[6]="1" 
+                                    loop = "".join(loop_list)
+                            pass
+                        valid_time = _alarm["valid_time"]
+                        
+                        print("loop interval:{}".format(loop))
+                        alarm_content=_alarm["alarm_content"]
+                        if len(alarm_content) == 0:
+                            alarm_content = "小瑞提醒您了"
+                        H_H = valid_time.split("-") #9:00-10:00
+                        start_time = H_H[0].split(":")
+                        end_time = H_H[1].split(":")
+                        alarm_tmp["name"]=alarm_content
+                        alarm_tmp["loop"]=loop
+                        alarm_tmp["state"]="1"
+                        alarm_tmp["time"]=""
+                        alarm_tmp["ringTimes"]=1
+                        alarm_tmp["alarmMode"]="ring"
+                        alarm_tmp["shakeType"]="none"
+                        alarm_tmp["interval"]=1
+                        alarm_tmp["date"]=0  #只有不是循环的就需要解析日期 星期为000000
+                        alarm_tmp["valid_time"]=valid_time
+                        alarm_tmp["repeat_min"]=repeat_min
+                        save_alarm_tmp.append(alarm_tmp)
+                        count+=1
+                        print("count:{}".format(count))
+                        need_alarm_info = "闹钟{},".format(count)
+                        #[
+                        # {'valid_time': '9:00-12:00', 'date': 0, 'time': '', 'ringTimes': 1, 'repeat_min': 60, 'ringUrl': None, 'state': '1', 'alarmMode': 'ring', 'loop': '1111111', 'interval': 1, 'name': '喝水', 'index': 0, 'shakeType': 'none'}, 
+                        # {'time': '11:02', 'ringTimes': 1, 'single': 1, 'ringUrl': None, 'date': '2025-08-07', 'state': '1', 'name': '喝水', 'index': 1, 'alarmMode': 'ring', 'shakeType': 'none', 'loop': '0000000'}, 
+                        # {'time': '11:03', 'ringTimes': 1, 'single': 1, 'ringUrl': None, 'date': '2025-08-07', 'state': '1', 'name': '小瑞提醒您了', 'index': 2, 'alarmMode': 'ring', 'shakeType': 'none', 'loop': '0000000'}
+                        #]
+                        #[
+                        # {
+                        # 'alarm_timer': '', 
+                        # 'repeat_day': [], 
+                        # 'repeat_min': 60, 
+                        # 'valid_time': '9:00-12:00', 
+                        # 'alarm_content': '喝水', 'alarm_type': '重复'
+                        #}]
+                        if len(_alarm["alarm_content"]) != 0:
+                            if len(repeat_day) != 0 and any("-" in item for item in repeat_day) != 0:
+                                need_alarm_info+=repeat_day+','
+                            need_alarm_info += "{}点{}分到{}点{}分 每隔{}分,提醒您该{}".format(start_time[0],start_time[1],end_time[0],end_time[1],repeat_min,alarm_content)
+                        else:
+                            if len(repeat_day) != 0 and any("-" in item for item in repeat_day) != 0:
+                                need_alarm_info+=repeat_day+','
+                            need_alarm_info += "{}点{}分到{}点{}分 每隔{}分,{}".format(start_time[0],start_time[1],end_time[0],end_time[1],repeat_min,alarm_content)
+                        break
 
                 else:
                     return [-1]
+            alarm_count = len(self.alarm_array)
+            index = alarm_count
+            for info in save_alarm_tmp:
+                info["ringUrl"] = None
+                info["index"] = index #0 1 2 3 
+                self.alarm_array.append(info)
+                index+=1
+            
         except Exception as e:
                 usys.print_exception(e)
-                return [-1]
-        if ret == 0:
-            self.alarm_array = alarm_array_tmp
-            EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])
-        return [ret,ret_str]
-    
-    def AI_delete_alarm(self,event=None,Num=None):#删除闹钟
+                return [-1] 
         
-        EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])
+        if count != 0:#当有有效闹钟数据时
+            print("保存闹钟新建数据")
+            print("self.alarm_array = {}".format(self.alarm_array))
+            self.alarm_array.sort(key=lambda x: x['index'])
+            EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
+            EventMesh.publish("GET_NEED_ALARM_REPORT_INFO")
+        return [count,need_alarm_info]
+    def get_week_str(self,week):
+        week_str = ""
+        if week == 7:
+            week_str = "周日"
+        elif week == 1:
+            week_str = "周一"
+        elif week == 2:
+            week_str = "周二"
+        elif week == 3:
+            week_str = "周三"
+        elif week == 4:
+            week_str = "周四"
+        elif week == 5:
+            week_str = "周五"
+        elif week == 6:
+            week_str = "周六"
+        return week_str
+    def read_alarm_list(self,event=None,Num=None):#读闹钟全列表
+        alarmlist_TTS_str =""#闹钟全列表播放tts字符串
+        if len(self.alarm_array) == 0:
+            alarmlist_TTS_str = "当前闹钟列表没有闹钟信息"
+            EventMesh.publish("play_tts",[alarmlist_TTS_str,1])
+            return
+        #alarm=[
+        # {alarm_tmp["name"]=alarm_content
+        # alarm_tmp["loop"]=loop
+        # alarm_tmp["state"]="1"
+        # alarm_tmp["time"]=""
+        # alarm_tmp["ringTimes"]=1
+        # alarm_tmp["alarmMode"]="ring"
+        # alarm_tmp["shakeType"]="none"
+        # alarm_tmp["interval"]=1
+        # alarm_tmp["date"]=0  #只有不是循环的就需要解析日期 星期为000000
+        # alarm_tmp["valid_time"]=valid_time
+        # alarm_tmp["repeat_min"]=repeat_min
+        # alarm_tmp["ringUrl"] = None:"铃声地址,空为默认地址",
+        # alarm_tmp["index"]=0}
+
+        # {alarm_tmp["name"]=alarm_content
+        # alarm_tmp["loop"]=loop #不需要判断星期是否符合条件
+        # alarm_tmp["state"]="1"
+        # alarm_tmp["time"]=alarm_timer
+        # alarm_tmp["ringTimes"]=1
+        # alarm_tmp["alarmMode"]="ring"
+        # alarm_tmp["shakeType"]="none"
+        # alarm_tmp["single"]=1
+        # alarm_tmp["date"]=repeat_day #单次提醒的年月日}
+        # alarm_tmp["index"]=0
+        # alarm_tmp["ringUrl"] = None:"铃声地址,空为默认地址",
+        #}
 
-    def AI_alarm_close(self):
+        # {alarm_tmp["name"]=alarm_content
+        # alarm_tmp["loop"]=loop
+        # alarm_tmp["state"]="1"
+        # alarm_tmp["time"]=alarm_timer
+        # alarm_tmp["ringTimes"]=1
+        # alarm_tmp["alarmMode"]="ring"
+        # alarm_tmp["shakeType"]="none"
+        # alarm_tmp["ringUrl"] = None:"铃声地址,空为默认地址",
+        # alarm_tmp["index"]=0}
+    #         {
+    #     "cmd":"alarm_list",
+    #     "ts":1738283829,
+    #     "msg":"下发闹钟列表",
+    #     "data":[
+    #         {
+    #             "name":"闹钟名称",
+    #             "loop":"0101001",
+    #             "state":"0/1 0表示关闭,1表示开启",
+    #             "time":"14:34",
+    #             "ringTimes":1/2/3,
+    #             "alarmMode":"ring表示响铃,shake表示震动,both表示都执行",
+    #             "shakeType":"short表示短震动,long表示长震动,none表示不震动",
+    #             "ringUrl":"铃声地址,空为默认地址",
+    #             "index":索引,0~9,最多 10个闹钟,删除闹钟重新排序
+    #         }
+    #     ]
+    # }
+        # ]
+        time_tuple = utime.localtime()#获取当前日期&时间的元组
+        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]
+        alarmlist_TTS_str += "当前闹钟信息如下:"
+        for i,_alarm in enumerate(self.alarm_array):
+            if "interval" in _alarm :#间隔提醒闹钟
+                continue
+
+            state = _alarm["state"]
+            loop = _alarm["loop"]
+            descrp = _alarm["name"]
+            set_hour = int((_alarm["time"]).split(":")[0])
+            set_min = int((_alarm["time"]).split(":")[1])
+            
+            week = ""
+            final_sentence = ""
+            for n,we in enumerate(loop):
+                week_t = n
+                if we == "1":
+                    if n == 0:
+                        week_t = 7
+                    final_sentence+=self.get_week_str(week_t)+","
+                    print("final_sentence = {}".format(final_sentence))
+                    week = final_sentence.rstrip(",")
+            if len(week) != 0: 
+                alarmlist_TTS_str += "闹钟{},{},{}点{}分提醒您:{}。".format(i+1,week,set_hour,set_min,descrp)
+            else:
+                alarmlist_TTS_str += "闹钟{},{}点{}分提醒您:{}。".format(i+1,set_hour,set_min,descrp)
+                pass
+        print("self.alarmlist_TTS_str = {}".format(alarmlist_TTS_str))
+        EventMesh.publish("play_tts",[alarmlist_TTS_str,1])
+    def AI_delete_alarm(self,event=None,Num=None):#删除闹钟
+        self.alarm_array =[]#闹钟队列清空
+        clear_ttr = "闹钟列表已清空"
+        try:
+            EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
+        except Exception as e:
+            usys.print_exception(e)
+            clear_ttr = "清除闹钟列表失败"
+        return clear_ttr
+    def delete_single_alarm(self,event=None,Num=None): #删除单个闹钟
+        if len(self.alarm_array) == 0:
+            return
+        if len(self.alarm_array) >= Num: #只有大于等于列表个数才能删除对应闹钟信息
+            self.alarm_array.pop(Num)
+            EventMesh.publish("set_storage_config",["alarm_list",self.alarm_array])
+            pass
+
+    def AI_alarm_close(self,event=None,Num=None):
+        print("AI_alarm_close")
+        self.alarm_timer_sta = 0
         self.AI_alarm_timer.stop()
+    def get_need_alarm_report_info(self,event=None,Num=None):
+        print("上报闹钟协议->IOT平台")
+        alarm_list = []
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        if len(self.alarm_array) > 0:
+            for _alarm in self.alarm_array:
+                alarm_info = {}
+                if len(_alarm["name"]) == 0:
+                    _alarm["name"] = "闹钟"
+
+                alarm_info["name"] = _alarm["name"]
+                alarm_info["loop"] = _alarm["loop"]
+                alarm_info["state"] = _alarm["state"]
+                alarm_info["time"] = _alarm["time"]
+                alarm_info["ringTimes"] = _alarm["ringTimes"]
+                alarm_info["alarmMode"] = _alarm["alarmMode"]
+                alarm_info["shakeType"] = _alarm["shakeType"]
+                alarm_list.append(alarm_info)
+        alarm_send = {
+            "cmd":"post_alarm",
+            "ts":time_tmp,
+            "msg":"上报闹钟",
+            "data":alarm_list
+        }
+        EventMesh.publish("REPORT_ALARM_TO_IOT",alarm_send)
+        return alarm_send
+
+        
+
+#日程提醒
+class schedule():
+    """
+    sjon格式{
+        # {
+        #     "cmd":"schedule",
+        #     "ts":1738283829,
+        #     "msg":"下发日程列表",
+            "data":[
+                "title":"日程名称",
+                "description":"提醒内容",
+                "repeat":1~4播报重复次数,
+                "date":"日期,yyyy-MM-dd",
+                "时间":"HH:mm",
+                "index": 0~9 排序
+        #     ]
+        # }
+    }
+    """
+    #最多只能设置五个闹钟
+    def __init__(self):
+    
+        self.schedule_array = EventMesh.publish("get_storage_config","schedule")#读取闹钟数组
+        if self.schedule_array is None:
+            self.schedule_array =[]
+            print("self.schedule_array =[]")
+
+        self.alarm_min_repeat_tmp = 0
+        self.minute_now_old = 0
+        self.alarm_min_one_tmp = 0
+        self.schedule_count = len(self.schedule_array)#日程个数
+        print("日程个数 ={}".format(self.schedule_count))
+        self.is_schedule = 0
+        self.old_minute = 0
+        EventMesh.subscribe("AI_schedule_open",self.AI_schedule_open)#
+        
+
+    def AI_schedule_open(self,event=None,msg=None):
+        if self.schedule_array == None:
+            return
+        if len(self.schedule_array) == 0:
+            return
+        # print("AI_alarm_open")
+        alarm_TTS_str = ""
+        alarm_tts_info = {}
+        now_time = utime.localtime()
+        if self.is_schedule == 1: #正在响铃不需要检查
+            if now_time[4] != self.old_minute: #下一个一分钟再次检查
+                self.old_minute = now_time[4]
+                return
+        self.old_minute = now_time[4]
+        self.is_schedule = 0
+        if len(self.schedule_array) != 0:
+        # {
+        #     "cmd":"schedule",
+        #     "ts":1738283829,
+        #     "msg":"下发日程列表",
+        #     "data":[
+        #         "title":"日程名称",
+        #         "description":"提醒内容",
+        #         "repeat":1~4播报重复次数,
+        #         "date":"日期,yyyy-MM-dd",
+        #         "时间":"HH:mm",
+        #         "index": 0~9 排序
+        #     ]
+        # }
+       
+        
+        # 'ts': 1754360964672, 'cmd': 'schedule'}
+            current_index = 0
+            for i,alarm in enumerate(self.schedule_array):
+                alarm_tts_info = {}
+                self.is_schedule = 0
+                # print("alarm:{}".format(alarm))
+                date = alarm["date"]
+                date_year = int(date.split("-")[0])
+                date_month = int(date.split("-")[1])
+                date_day = int(date.split("-")[2])
+                set_hour = int(((alarm["time"]).split(':'))[0])
+                set_min = int(((alarm["time"]).split(':'))[1])
+
+                time_tuple = utime.localtime()#获取当前日期&时间的元组
+                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 year_now == date_year and month_now == date_month and date_day == day_now and set_hour == hour_now and set_min == minute_now: #该提醒了
+                    alarm_tts_info = alarm
+                    self.is_schedule = 1
+                    current_index = i
+                    break
+            if self.is_schedule == 1: #需要执行闹钟响铃声
+                self.schedule_array.pop(current_index)
+                alarm_TTS_str = alarm_tts_info["description"]
+                AringTimes  = alarm_tts_info["repeat"]
+                base_sentence = "{}".format(alarm_TTS_str)
+                if AringTimes == 0:
+                    AringTimes = 1
+                repeat_sentence = (base_sentence + ",") * AringTimes  # 重复5次并加逗号分隔
+                final_sentence = repeat_sentence.rstrip(",")
+                
+                EventMesh.publish("play_tts",[final_sentence,1])  #播放tts闹钟文本内容
+                EventMesh.publish("set_storage_config",["schedule",self.schedule_array])#读取闹钟数组
+                print("日程:{} self.schedule_array :{}".format(final_sentence,self.schedule_array))
+
 
+        
\ No newline at end of file
index 38d9214..b277a3b 100644 (file)
@@ -223,3 +223,5 @@ class EVENT:
     START_BLOOD_OXYGEN = "STARTT_BLOOD_OXYGEN" 
     GET_BLOOD_OXYGEN = "GET_BLOOD_OXYGEN"
     STOP_BLOOD_OXYGEN = "STOP_BLOOD_OXYGEN"
+    CHANNEL_IOT_WEB_SEND = "CHANNEL_IOT_WEB_SEND"
+    
index 73c9839..81848c3 100644 (file)
@@ -176,7 +176,6 @@ def main_init():
                             import ai_VC as _ai
                         except Exception as e:
                             usys.print_exception(e) 
-
         #app.append_manager(intervManager())
         try:
             app.append_manager(_ai.getStorageDataManager())
@@ -195,12 +194,78 @@ def main_init():
             app.append_manager(_ai.device_res_author())
         except Exception as e:
             usys.print_exception(e)     
-        
+       
+       
+        # from iot_websocket import TSockManager,LK_ProtoCol,IOTProtoColResolver,IOTWebsocketProtoCol,IOTWebsocketMang,IOTSendCmdManager,IotProtoColResolver,IOTWeb_HRProtoCol
+        # import protocol
+        try:
+            from usr.motor import motorEventManager
+            app.append_manager(motorEventManager())
+        except Exception as e:
+            usys.print_exception(e) 
+            from motor import motorEventManager
+            app.append_manager(motorEventManager())
+
+        try:
+            from usr.voice_record import VOICE_RECORD
+            app.append_manager(VOICE_RECORD())
+        except Exception as e:
+            usys.print_exception(e) 
+            from voice_record import VOICE_RECORD
+            app.append_manager(VOICE_RECORD())
+        try:
+            import usr.protocol as pro
+        except Exception as e:
+            usys.print_exception(e) 
+            import protocol as pro
+        try:
+            # app.append_manager(pro.IOTSendCmdManager())
+            app.append_manager(pro.IOTWebLocationManager())
+            app.append_manager(pro.sosInfoCallManager())
+            pcr = pro.ProtoColResolver()
+            pcr.add_support(pro.IOTWeb_HRProtoCol())
+            pcr.add_support(pro.IOTWeb_LocateNowProtoCol())
+            pcr.add_support(pro.IOTWeb_post_sosProtoCol())
+            pcr.add_support(pro.IOTWeb_post_device_stateProtoCol())
+            pcr.add_support(pro.IOTWeb_post_alarmProtoCol())
+            pcr.add_support(pro.IOTWeb_post_locationProtoCol())
+            pcr.add_support(pro.IOTWeb_locatedurationProtoCol())
+            pcr.add_support(pro.IOTWeb_FindDeviceProtoCol())
+            # pcr.add_support(pro.IOTWeb_alarm_configProtoCol())
+            pcr.add_support(pro.IOTWeb_alarm_listProtoCol())
+            pcr.add_support(pro.IOTWeb_sos_listProtoCol())
+            pcr.add_support(pro.IOTWeb_volumeProtoCol())
+            pcr.add_support(pro.IOTWeb_sos_configProtoCol())
+            pcr.add_support(pro.IOTWeb_get_ringtoneProtoCol())
+            pcr.add_support(pro.IOTWeb_voice_recordProtoCol())
+            pcr.add_support(pro.IOTWeb_text_msgProtoCol())
+            pcr.add_support(pro.IOTWeb_scheduleProtoCol())
+            pcr.add_support(pro.IOTWeb_switch_bt_stateProtoCol())
+            pcr.add_support(pro.IOTWeb_bt_scanProtoCol())
+            pcr.add_support(pro.IOTWeb_bt_scan_restProtoCol())
+            pcr.add_support(pro.IOTWeb_ringtone_listProtoCol())
+            pcr.add_support(pro.IOTWeb_connect_btProtoCol())
+            pcr.add_support(pro.IOTWeb_disconnect_btProtoCol())
+
+
+            pcr.add_support(pro.IOTWeb_get_bt_stateProtoCol())
+            pcr.add_support(pro.IOTWeb_put_voice_msg_stateProtoCol())
+            pcr.add_support(pro.IOTWeb_new_voice_msg_listProtoCol())
+            pcr.add_support(pro.IOTWeb_get_new_voice_msgProtoCol())
+            pcr.add_support(pro.IOTWeb_new_voice_msgProtoCol())
+            sm = pro.SockMangager()
+
+            sm.add_support_resolver(pcr)
+            app.append_manager(sm)
+            print("init11.0:{}".format(utime.localtime()))   
+            
+        except Exception as e:
+            usys.print_exception(e) 
+
         try:
             app.append_manager(_ai.AI_VC())
         except Exception as e:
             usys.print_exception(e) 
-              
     except Exception as e:
         usys.print_exception(e)   
         
@@ -209,7 +274,7 @@ def main_init():
     EventMesh.debug_log("init11:{}".format(utime.localtime()))    
     
     #EventMesh.publish("open_power_on", 1)#
-    # pcr = protocol.ProtoColResolver()
+    # pcr = pro.ProtoColResolver()
     # pcr.add_support(protocol.LK_ProtoCol())
     # pcr.add_support(protocol.PING_ProtoCol())
     # pcr.add_support(protocol.KA_ProtoCol())
index de38bf6..d863a95 100644 (file)
@@ -639,6 +639,8 @@ if EventMesh.model == "D10":
                                     if len(number[0]) != 0:
                                         EventMesh.debug_log("phone 6")
                                         EventMesh.publish("set_callnumer_cb",number[0])   
+    
+    
     WL_timer = osTimer()   
     def WL_timer_cb(*args):   
         get_call = EventMesh.publish("get_call_state") 
@@ -918,7 +920,7 @@ if EventMesh.model == "D10":
         def post_processor_after_instantiation(self):
             EventMesh.debug_log("post_processor_after_instantiation:1")
             """订阅此类所有的事件到 EventMesh中"""
-            voiceCall.setCallback(voice_callback)
+            # voiceCall.setCallback(voice_callback)
             EventMesh.subscribe("screen_get_ope", self.get_device_ope)
             EventMesh.subscribe("screen_get_sig", self.get_signal)
             EventMesh.subscribe("screen_get_time", self.get_time)
@@ -2745,7 +2747,7 @@ if EventMesh.model == "D10":
             if not self.imei:
                 self.imei = modem.getDevImei()
             
-            # self.imei = "866610001011658" #860132060128634
+            # self.imei = "860132064231574" #860132060128634
             return self.imei
 
         def get_cid(self, topic, msg):
index cd31639..b0c9bf8 100644 (file)
@@ -9,7 +9,7 @@ import _thread
 import usys
 
 
-motor_pin = Pin(Pin.GPIO20, Pin.OUT, Pin.PULL_PD, 0)
+motor_pin = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
 def open_motor():#开马达
     motor_pin.write(1)
 
@@ -55,10 +55,6 @@ class motorEventManager(Abstract):#马达事件
 
     # msg 0马达使能 1 马达振动时间100ms单位 2 震动次数 3 间隔时间振动 4 是否需要长振 5 长振时间  6间隔时间长振 7长振次数1一次 要为200ms的倍数
     def set_motor_time(self,event,msg):
-        open_power = EventMesh.publish("get_power_on_state")#获取开机标识
-        if open_power != None:
-            if open_power == 0:
-                return
         if msg != None:
             self.motor_enable = msg[0]
             if self.motor_enable == 1: #马达使能
@@ -77,7 +73,7 @@ class motorEventManager(Abstract):#马达事件
             close_motor()
             EventMesh.publish("close_motor_infor")#关闭马达和定时器
             return
-        if self.motor_mode == 1:#
+        if self.motor_mode == 1:# 持续振动时间100单位 长振
             if self.motor_total_time > 0:
                 self.motor_total_time-=1
                 if self.motor_total_time > 0:
@@ -86,7 +82,7 @@ class motorEventManager(Abstract):#马达事件
                     close_motor()
                     EventMesh.publish("close_motor_infor")#关闭马达和定时器
                     return
-        elif self.motor_mode == 2:#
+        elif self.motor_mode == 2:# 间隔振动
             # print("self.motor_count",self.motor_count,self.motor_open_time,self.motor_close_time,self.motor_total_time)
             if self.motor_count % (self.motor_open_time) < self.motor_close_time: # 4 4 2 1%4 = 1 2%4 = 2 3%4 = 3
                 open_motor()
index 2ab81a5..2650b7b 100644 (file)
@@ -269,787 +269,2669 @@ def mqtt_client_dev_init():#一机一密
     # 设置异常回调
     client.error_register_cb(mqtterr_cb)
     return client
+######################IOT######################
+import sms
+import voiceCall
+import quecgnss
+import wifiScan
+from misc import Power,USB
+def wifiScan_cb(args):
+    print("wifi_data:{}".format(args))
+    EventMesh.publish(constants.EVENT.WIFIINFO, args)
+    wifiScan.control(0)
+class IOTWebLocationManager(Abstract):
+
+    def __init__(self):
+        self.gps = None
+        #self.match = GPSMatch()
+        self.timer_read_GPS_info = osTimer()
+        self.timer_sos_report_info = osTimer()
+        self.wifi_data = []
+        self.cell_data = []
+        self.location_timer_count = 0
+        self.location_check_data_timer_count = 0
+        self.GGA_count = 0
+        self.RMC_A_count = 0
+        self.location_type = 0 #定位类型,0:正常定位,有gps数据或60秒关闭;1:测试模式,只有发CLOSE_LOCATION消息才关闭
+        self.location_flag = 0
+        self.start_location_flag = 0
+        self.location_thread_id  = 0
+        self.location_queue = Queue(100)
+        self.lpm_fd = None
+        self.start_agps = 0
+        self.sos_report_flag=0
+        quecgnss.gnssEnable(0)
+
+    def post_processor_after_instantiation(self):
+        EventMesh.subscribe(constants.EVENT.START_LOCATION, self.start_location)
+        EventMesh.subscribe(constants.EVENT.WIFIINFO, self.WIFI_INFO)
+        EventMesh.subscribe(constants.EVENT.WIFISCANOPEN,self.WIFI_scan_open)
+        EventMesh.subscribe(constants.EVENT.CLOSE_LOCATION,self.close_location)
+        EventMesh.subscribe("get_location_flag",self.get_location_flag)
+        #EventMesh.subscribe(constants.EVENT.GPSCLOSE, self.gps_close)
+    def get_location_flag(self, event, msg):
+        return self.location_flag
+    
+    def sos_report_info(self):
+        EventMesh.debug_log("sos_report_info:")
+        if self.sos_report_flag == 1:
+            return
+        self.soswifi_data = []
+        self.soscell_data = []
+        self.sos_report_flag = 1
+        self.timer_sos_report_info.start(3000, 1, self.sos_timer)
+    
+    def close_sos(self):
+        self.soswifi_data = []
+        self.soscell_data = []
+        self.sos_report_flag=0
+        self.timer_sos_report_info.stop()
+
+    
+    def sos_timer(self, *args, **kwargs):
+        if self.sos_report_flag == 1:
+            try :   
+                #检查wifi数据
+                if self.soswifi_data == [] or (self.soswifi_data != [] and self.soswifi_data[0] == 0):#and self.wifi_data[0] <= 0:
+                    EventMesh.publish(constants.EVENT.WIFISCANOPEN)
+                    
+                #检查基站数据
+                if self.soscell_data== []:   
+                    data_tmp = net.getCellInfo()
+                    if(len(data_tmp)>=2):
+                        for cell in data_tmp:
+                            if cell and cell[0][0] == 0 and len(cell[0]) > 1:
+                                self.soscell_data = cell
+                                break
+                if self.soscell_data != [] and self.soswifi_data != []:
+                    self.close_sos()
+                    self.Location_send([WEB_CMD_ENUM.SOS_REPORT_S_CMD,self.soswifi_data,self.soscell_data])
+
+            except Exception as e:
+                usys.print_exception(e)
+
+    def start_location(self, event, msg):
+        self.location_queue.put(msg)#测试类型入队
+        self.wifi_data = []
+        self.cell_data = []
+        print("start_location:{} self.location_flag:{}".format(msg,self.location_flag))
+        if( self.location_flag == 1):
+            return
+        self.location_flag = 1
+        _thread.stack_size((9+5)*1024)
+        self.location_thread_id  = _thread.start_new_thread(self.location_thread, ())
+        _thread.stack_size(8*1024)
+        # self.timer_read_GPS_info.start(1000, 1, self.location_timer)
+        # if msg == WEB_CMD_ENUM.SOS_REPORT_S_CMD:
+        #     self.sos_report_info()
+        #     pass
+        # elif msg == WEB_CMD_ENUM.GPS_REPORT_S_CMD:
+        #     self.gps_report_init()
+            # pass
+    def gps_report_init(self):
+
+        EventMesh.debug_log("start_location:")
+        if self.location_flag == 1:
+            return
+        self.wifi_data = []
+        self.cell_data = []
+        self.location_timer_count = 0
+        self.location_flag = 1
+        self.timer_read_GPS_info.start(3000, 1, self.location_timer)
+
+
+    def close_location(self,event,msg):
+        self.location_flag = 0
+        if  wifiScan.getState() == True:
+            print("关闭定位线程失败")
+            wifiScan.control(0)
+        # self.timer_read_GPS_info.stop()
+        if self.location_thread_id == 1:
+            try:
+                _thread.stop_thread(self.location_thread_id)
+            except Exception as e:
+                pass
+        self.location_thread_id=0
+
+        
+
+    def WIFI_INFO(self, event, msg):
+        self.wifi_data = msg
+
+    def WIFI_scan_open(self, event, msg):
+
+        if wifiScan.getState() == False :
+            self.wifi_data = []
+            wifiScan.control(1)
+            wifiScan.setCfgParam(6, 2, 5,  0)  #设置WiFi参数,10秒上层,两轮,最多6个,6秒底层,PS优先
+            wifiScan.setCallback(wifiScan_cb) #注册回调函数
+            wifiScan.asyncStart()
+            #EventMesh.debug_log("wifiScan.asyncStart")
+        
+    def location_timer(self, *args, **kwargs):
+        if self.location_flag == 1:
+            try :   
+                #检查wifi数据
+                if self.wifi_data == [] or (self.wifi_data != [] and self.wifi_data[0] == 0):#and self.wifi_data[0] <= 0:
+                    EventMesh.publish(constants.EVENT.WIFISCANOPEN)
+                    
+                #检查基站数据
+                if self.cell_data == []:   
+                    data_tmp = net.getCellInfo()
+                    if(len(data_tmp)>=2):
+                        for cell in data_tmp:
+                            if cell and cell[0][0] == 0 and len(cell[0]) > 1:
+                                self.cell_data = cell
+                                break
+                if self.cell_data != [] and self.wifi_data != []:
+                    self.close_location(0,0)
+                    self.Location_send([WEB_CMD_ENUM.POST_LOCATION_S_CMD,self.wifi_data,self.cell_data])
+
+            except Exception as e:
+                usys.print_exception(e)
+       
+    def Location_send(self, msg) :
+        EventMesh.debug_log("Location_send1")
+        if self.location_queue.empty() == True:
+            return
+        EventMesh.debug_log("Location_send2")
+        print("Location_send1")
+        while True:
+            if self.location_queue.empty() == False:
+                TYPE = self.location_queue.get()
+                # (5, [('70:2A:D7:63:BD:B4', -38), ('C0:94:AD:80:21:5F', -61), ('D8:38:0D:05:1F:E3', -65), ('08:9E:84:E7:A6:38', -73), ('B0:44:14:BC:13:B0', -73)])
+                wifi_tmp = []
+                print("wifi_num:{}".format(wifi_num))
+                wifi_num = msg[0][0]
+                if  wifi_num == 0:
+                    wifi_tmp = []
+                else: #([], [], [(0, 69483137, 1120, 1, 385, 30504, 100, -75, -8), (3, 111950593, 1120, 1, 58, 30504, 1650, -98, -19), (3, 219097617, 1120, 17, 76, 30504, 2452, -106, -23), (3, 102345712, 1120, 1, 58, 30504, 3740, -96, -18)])
+                    
+                    wifi_tmp_data = msg[0][1]
+                    print(wifi_tmp_data)
+                    for i in range(wifi_num):
+                        list_data = {}
+                        list_data["mac"] = str(wifi_tmp_data[i][0])
+                        list_data["rsi"] = str(wifi_tmp_data[i][1])
+                        # list_data = "{},{}".format(wifi_tmp_data[i][0],wifi_tmp_data[i][1])
+
+                        wifi_tmp.append(list_data)
+                    pass
+                # ([(flag, cid, mcc, mnc, lac, arfcn, bsic, rssi)], [(flag, cid, licd, mcc, mnc, lac, uarfcn, psc, rssi)], [(flag, cid, mcc, mnc, pci, tac, earfcn, rssi, rsrq),...])
+                date_tmp = utime.localtime()
+                time_tmp = utime.mktime(date_tmp)
+                celList = []
+                if msg[1] != []:
+                    for CELL in msg[1] :
+                        print("CELL:{}".format(CELL))
+                        CELL_data = {}
+                        CELL_data["mcc"] = str(CELL[2])
+                        CELL_data["mnc"] = str(CELL[3])
+                        CELL_data["lac"] = str(CELL[4])
+                        CELL_data["cid"] = str(CELL[1])
+                        CELL_data["rsi"] = str(CELL[7])
+
+
+                        # CELL_data += str(CELL[2]) +"," #MCC
+                        # CELL_data += str(CELL[3]) +"," #MNC
+                        # CELL_data += str(CELL[4]) +"," #LAC
+                        # CELL_data += str(CELL[7]) +"," #RSSI
+                        celList.append(CELL_data)
+                s_msg=""
+                s_cmd = ""
+                if TYPE == WEB_CMD_ENUM.POST_LOCATION_S_CMD:
+                    s_msg = "上报经纬度"
+                    s_cmd = "post_location"
+                elif TYPE == WEB_CMD_ENUM.POST_SOS_S_CMD:
+                    s_msg = "上报SOS求救"
+                    s_cmd = "post_sos"
+                send_data = {
+                    "cmd":s_cmd,
+                    "ts":int(time_tmp),
+                    "msg":s_msg,
+                    "data":{
+                        "gps": {
+                            "longitude": "0",
+                            "latitude": "0",
+                            "located": "0",
+                            "speed": "0"
+                        },
+                        "wifiList":wifi_tmp,
+                        "celList":celList
+                        
+                    }
+                }
+                print("TYPE{}".format(TYPE))
+                EventMesh.publish(TYPE,send_data)
+            else:
+                self.location_thread_id=0
+                EventMesh.publish(constants.EVENT.CLOSE_LOCATION)
+                break
+
+
+    def location_thread(self):
+        
+        self.wifi_data = []
+        print("location_thread self.location_flag {}".format(self.location_flag))
+        while self.location_flag == 1:
+            try :   
+
+                #检查wifi数据
+                if self.wifi_data == [] or (self.wifi_data != [] and self.wifi_data[0] == 0):#and self.wifi_data[0] <= 0:
+                    EventMesh.publish(constants.EVENT.WIFISCANOPEN)
+                    
+                #检查基站数据
+                if self.cell_data == []:   
+                    print("location_thread")
+                    data_tmp = net.getCellInfo()
+                    if(len(data_tmp)>=2):
+                        for cell in data_tmp:
+                            if cell and cell[0][0] == 0 and len(cell[0]) > 1:
+                                self.cell_data = cell
+                                break
+
+                if self.cell_data != [] and self.wifi_data != []:
+                    self.Location_send([self.wifi_data,self.cell_data])
+                    
+                    break
+                
+            except Exception as e:
+                usys.print_exception(e)
+                EventMesh.publish(constants.EVENT.CLOSE_LOCATION)#关闭定位 
+        wifiScan.control(0)
+
+                    
+
+import uwebsocket
+import sim
+# 设备主动上报后台返回cmd的字符串
+DEVICE_REPORT_RETURN_STRING = "post_rest" 
+# 服务器主动下发给设备的cmd的字符串
+IOT_AUTO_REPORT_RETURN_STRING = "dispatch_rest" 
+MAGIC_STR = len("FFFE")
+VERSION_STR =len("03")
+TYPE_STR = len("03")
+PLAYLOAD_STR = len("0000")
+PROTOCLO_LEN = MAGIC_STR+VERSION_STR+TYPE_STR+PLAYLOAD_STR+len('{')+len('}')+len("cmd:")+len("data:")+len("ts:")
+
+class WEB_CMD_ENUM:
+    HR_R_CMD = "post_heart_beat_R"
+    HR_S_CMD = "post_heart_beat_S"
+
+    POST_LOCATION_R_CMD = "post_location_R"
+    POST_LOCATION_S_CMD = "post_location_S"
+
+    POST_SOS_R_CMD = "post_sos_R"
+    POST_SOS_S_CMD = "post_sos_S"
+
+    POST_DEVICE_STATE_R_CMD = "post_device_state_R"
+    POST_DEVICE_STATE_S_CMD = "post_device_state_S"
+
+    POST_ALARM_R_CMD = "post_alarm_R"
+    POST_ALARM_S_CMD = "post_alarm_S"
+
+
+    FIND_DEVCE_R_CMD = "find_device_R"
+    FIND_DEVCE_S_CMD = "find_device_S"
+
+    LOCATION_NOW_R_CMD = "locate_now_R"
+    LOCATION_NOW_S_CMD = "locate_now_S"
+
+    LOCATION_DURATION_R_CMD = "locate_duration_R"
+    LOCATION_DURATION_S_CMD = "locate_duration_S"
+
+    ALARM_CONFIG_R_CMD = "alarm_config_R"
+    ALARM_CONFIG_S_CMD = "alarm_config_S"
+
+    ALARM_LIST_R_CMD = "alarm_list_R"
+    ALARM_LIST_S_CMD = "alarm_list_S"
+
+    SOS_LIST_R_CMD ="sos_list_R"
+    SOS_LIST_S_CMD ="sos_list_S"
+
+    SOS_CONFIG_R_CMD = "sos_config_R"
+    SOS_CONFIG_S_CMD = "sos_config_S"
+
+    DEVICE_SHAKE_STATE_R_CMD = "device_shake_state_R"
+    DEVICE_SHAKE_STATE_S_CMD = "device_shake_state_S"
+
+    RING_TONE_URL_R_CMD = "ring_tone_url_R"
+    RING_TONE_URL_S_CMD = "ring_tone_url_S"
+
+    VOLUME_R_CMD = "volume_R"
+    VOLUME_S_CMD = "volume_S"
+
+    TEXT_MSG_R_CMD = "text_msg_R"
+    TEXT_MSG_S_CMD = "text_msg_S"
+
+    VOICE_RECORD_R_CMD = "voice_record_R"
+    VOICE_RECORD_S_CMD = "voice_record_S"
+
+    GET_RINGTONE_R_CMD = "get_ringtone_R"
+    GET_RINGTONE_S_CMD = "get_ringtone_S"
+
+    RINGTONE_LIST_R_CMD = "ringtone_list_R"
+    RINGTONE_LIST_S_CMD = "ringtone_list_S"
+
+    SCHEDULE_R_CMD = "schedule_R"
+    SCHEDULE_S_CMD = "schedule_S"
+    
+    SWITCH_BT_STATE_R_CMD="switch_bt_state_R"
+    SWITCH_BT_STATE_S_CMD="switch_bt_state_S"
+
+
+    BT_SCAN_R_CMD="bt_scan_R"
+    BT_SCAN_S_CMD="bt_scan_S"
+
+    BT_STATE_R_CMD="bt_state_R"
+    BT_STATE_S_CMD="bt_state_S"
+
+    BT_SCAN_REST_R_CMD = "bt_scan_rest_R"
+    BT_SCAN_REST_S_CMD = "bt_scan_rest_S"
+
+    BT_CONNECT_RECORD_LIST_R="bt_connect_record_list_R"
+    BT_CONNECT_RECORD_LIST_S="bt_connect_record_list_S"
+
+    CONNECT_BT_R="connect_bt_R"
+    CONNECT_BT_S="connect_bt_S"
+
+    DISCONNECT_BT_R="disconnect_bt_R"
+    DISCONNECT_BT_S="disconnect_bt_S"
+
+    NEW_VOICE_MSG_R = "new_voice_msg_R"
+    NEW_VOICE_MSG_S = "new_voice_msg_S"
+
+    GET_NEW_VOICE_MSG_R="get_new_voice_msg_R"
+    GET_NEW_VOICE_MSG_S="get_new_voice_msg_S"
+
+    NEW_VOICE_MSG_LIST_R="new_voice_msg_list_R"
+    NEW_VOICE_MSG_LIST_S="new_voice_msg_list_S"
+
+    PUT_VOICE_MSG_STATE_R="put_voice_msg_state_R"
+    PUT_VOICE_MSG_STATE_S="put_voice_msg_state_S"
+
+    GET_BT_STATE_R="get_bt_state_R"
+    GET_BT_STATE_S="get_bt_state_S"
+
+class IOTSendCmdManager(Abstract):
+    #
+    def __init__(self):
+        self.send_data = ""
+        self.time_tmp = 0
+    def post_processor_after_instantiation(self):
+        EventMesh.subscribe("GET_IOT_WEB_SEND_CMD", self.get_iot_send_cmd)
+        print("IOTSendCmdManager")
+
+    def get_iot_send_cmd(self, event, msg):
+        date_tmp = utime.localtime()
+        self.time_tmp = utime.mktime(date_tmp)
+        if msg == WEB_CMD_ENUM.HR_S_CMD:
+            self.send_data = self.hr_send_data(self.time_tmp)
+            return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_LOCATION_S_CMD:
+            self.send_data = self.gps_send_data()
+            return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_SOS_S_CMD:
+            self.send_data = self.sos_wraing_send_data()
+            return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD:
+           self.send_data = self.device_report_state_send_data()
+           return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_ALARM_S_CMD:
+            self.send_data = self.alarm_config_send_data()
+        return self.send_data
+    
+    # 心率上报数据格式
+    def hr_send_data(self,time):
+        print("hr_send_data")
+        battery = (EventMesh.publish("screen_get_battery"))[1]
+        if battery >= 100 or battery == None:
+            battery = 100
+        hr_send_data = {
+            "cmd":"post_heart_beat",
+            "ts":time,
+            "msg":"心跳",
+            "data":{
+                "battery": int(battery)
+            }
+        }
+        return hr_send_data
+    
+    # gps上报数据格式
+    def gps_send_data(self):
+        gps_data = {
+            "cmd":"post_location",
+            "ts":self.time_tmp,
+            "data":{
+                "gps":{
+                    "longitude":"W,67",
+                    "latitude":"S,465",
+                    "direction":"FR",
+                    "speed":"45",
+                    "altude":"56",
+                    "count":"3"
+                },
+                "wifiList":[
+                    "89:78:78:67:89:98,-98"
+                ],
+                "celList":[
+                    "MCC,MNC,LAC,CID,RSSI"
+                ],
+                "btList":[
+                    "D4:78:65:67:89:78"
+                ]
+            }
+        }
+        return gps_data
+    
+    # sos警告上报数据格式
+    def sos_wraing_send_data(self):
+        sos_wraing_data ={
+                "cmd":"post_sos",
+                "ts":self.time_tmp,
+                "data":{
+                    "gps":{
+                        "longitude":"W,67",
+                        "latitude":"S,465",
+                        "direction":"FR",
+                        "speed":"45",
+                        "altude":"56",
+                        "count":"3"
+                    },
+                    "wifiList":[
+                        "89:78:78:67:89:98,-98"
+                    ],
+                    "celList":[
+                        "MCC,MNC,LAC,CID,RSSI"
+                    ],
+                    "btList":[
+                        "D4:78:65:67:89:78"
+                    ]
+                }
+            }
+        return sos_wraing_data
+    
+    #设备上报状态上报数据格式
+    def device_report_state_send_data(self):
+        device_report_data ={
+            "cmd":"post_device_state",
+            "ts":self.time_tmp,
+            "data":{
+                "mediaTitle":"haha",
+                "mediaState":"stop",
+                "cover":"899",
+                "volume":45
+            }
+        }
+        # HR_DATA=EventMesh.publish("GET_IOT_WEB_SEND_CMD",WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD)
+        # print("HR_DATA{}".format(HR_DATA))
+        #  EventMesh.publish(WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD,HR_DATA)
+        return device_report_data
+
+    #闹钟配置上报数据格式
+    def alarm_config_send_data(self):
+        alarm_data = {
+            "cmd":"post_alarm",
+            "ts":self.time_tmp,
+            "msg":"上报闹钟",
+            "data":[
+                {
+                    "name":"喝水",
+                    "loop":"0101001",
+                    "state":"0",
+                    "time":"14:34",
+                    "ringTimes":1,
+                    "alarmMode":"ring",
+                    "shakeType":"short"
+                }, 
+                {
+                    "name":"起床",
+                    "loop":"0101001",
+                    "state":"0",
+                    "time":"07:40",
+                    "ringTimes":1,
+                    "alarmMode":"ring",
+                    "shakeType":"short"
+                }
+            ]
+        }
+            
+        return alarm_data
+def playpolad_data(data):
+    if(isinstance(data, bytes) == 0 or len(data) <= PROTOCLO_LEN):
+        return
+
+    if data[0] != 0xff and data[1] !=0xfe and data[2] != 0x03 and data[3] !=0x03:
+        return
+    
+    print(type(data))
+    json_bytes = data[8:]
+    print(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7])
+    # 2. 将二进制JSON转换为字符串(使用UTF-8解码)
+    json_str = json_bytes.decode('utf-8')
+    print("解析出的JSON字符串:")
+    print(json_str)
+    print("\n" + "-"*50 + "\n")
+
+    # 3. 将JSON字符串转换为Python字典
+    try:
+        data_dict = ujson.loads(json_str)
+        print("解析后的字典数据:")
+        print(data_dict)
+        
+        # 可以直接访问字典中的字段
+        
+        cmd =  data_dict['cmd']
+        if cmd !=  None:
+            if cmd == DEVICE_REPORT_RETURN_STRING:
+                data_cmd =  data_dict['data']['cmd']
+                # {"cmd":"post_rest","ts":1753870158426,"data":{"cmd":"post_heart_beat","rest":"success","msg":"."}}
+                print("设备主动上报后台返回的数据 设备不需要回复")
+                EventMesh.publish(data_cmd+"_R",data_dict)
+            else:
+                # {"cmd":"locate_now","msg":"","data":"876226211472149","ts":1753870224117}
+                print("后台主动下发给设备 需要设备回复给后台的数据命令") #后台主动下发的数据不为dict类型
+                EventMesh.publish(cmd+"_R",data_dict)
+        else:
+            print("cmd is None") #下发的指令无不解析
+    except Exception as e:
+        print("解析JSON出错:", str(e))
+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
+#音频流数据格式
+#magic+version+type+msgid+playload_len+playload
+def protocol_audio_playload_data(data,msgid):
+    MAGIC =  (0xfffe).to_bytes(2,"big")
+    VERSION = (0x01).to_bytes(1,"big")#"03".encode('utf-8')
+    TYPE = (0x05).to_bytes(1,"big")
+    MSGID = msgid.to_bytes(4,"big")
+    DATA_LEN = (len(data)).to_bytes(4,"big")
+    heards_infor = b''
+    heards_infor = MAGIC+VERSION+TYPE+MSGID+DATA_LEN+data
+    return heards_infor
+
+class sosInfoCallManager(Abstract):
+    def __init__(self):
+        self.num = 0
+        self.num=0
+        self.num_len = 0
+        self.sos_list = []
+        self.sos_flag = 0
+        self.sos_timer1 = osTimer()
+        self.sos_timer2 = osTimer()
+        self.save_list = []
+        self.call_state = 0
+        self.sos_config = {}
+        self.phone110112 = ""
+        if EventMesh.publish("get_storage_config","sos_list") != None:
+            self.sos_list = EventMesh.publish("get_storage_config","sos_list")
+        if EventMesh.publish("get_storage_config","sos_config") != None:
+            self.sos_config= EventMesh.publish("get_storage_config","sos_config")
+        
+        # sos_list=[{"index":0,"phone":"15521469561"}, {"index":0,"phone":"15692025051"},{"index":0,"phone":"15521469561"}]
+        EventMesh.subscribe("call_out_cb", self.call_out_cb) 
+        EventMesh.subscribe("get_sos_flag", self.get_sos_flag) 
+
+    def post_processor_after_instantiation(self):
+        self.num = 0
+        self.sos_flag = 0
+        voiceCall.setCallback(self.voice_callback)
+        EventMesh.subscribe("set_sos_info_call", self.set_sos_info_call)
+        
+    def get_sos_flag(self,event,msg):
+        return self.sos_flag
+        # import EventMesh
+        # EventMesh.publish("set_sos_info_call")
+    def close_call_timer(self):
+        self.sos_timer2.stop()
+        pass
+    def start_phone110112(self):
+        if self.call_state == 0:
+            if self.sos_config != {}:
+                enable110 = self.sos_config["state"]
+                if enable110 == 1:
+                    p110 = self.sos_config["enable_110"]
+                    self.phone110112 = p110
+                    self.sos_timer1.start(2000, 0, self.phone110112_cb)
+        pass
+    def sos_call_out_phone(self, msg):#电话拨出去
+        if self.call_state == 0:
+            voiceCall.callStart(self.sos_phone_num)
+    def phone110112_cb(self,*argc):
+        if self.call_state == 0:
+            voiceCall.callStart(self.phone110112)
+            self.phone110112 = ""
+# if ("btStateSwitch".equals(testType)) {
+#             return testBtStateDispatch(deviceId);
+#         } else if ("btScan".equals(testType)) {
+#             return testBtScanDispatch(deviceId);
+#         } else if ("getBtState".equals(testType)) {
+#             return testGetBtStateDispatch(deviceId);
+#         } else if ("getConnectRecordList".equals(testType)) {
+#             return testGetConnectRecordListDispatch(deviceId);
+#         } else if ("connectBt".equals(testType)) {
+#             return testConnectBtDispatch(deviceId);
+#         } else if ("disconnectBt".equals(testType)) {
+#             return testDisconnectBtDispatch(deviceId);
+#         }
+    def set_sos_list_info(self,event,msg):
+        if self.sos_flag == 1:
+            pass
+        self.sos_list = msg
+
+        
+    def call_out_cb(self,event,phonenumber):
+        
+        if self.call_state == 0:
+            self.sos_phone_num = phonenumber
+            EventMesh.publish(constants.EVENT.START_LOCATION,WEB_CMD_ENUM.POST_SOS_S_CMD) #开始AL定位
+            self.sos_timer1.start(2000, 0, self.sos_call_out_phone)
+            self.sos_timer2.start(30000, 0, self.sos_time_out_phone)
+    def sos_time_out_phone(self, msg):#30s超时未打通或者信号不好则重新拨打
+        
+        if self.sos_flag == 1:
+            if self.call_state == 0 or self.call_state == 3 or self.call_state == 4:
+                voiceCall.callEnd() #挂断
+                self.set_sos_info_call(1,1)
+            pass #再次拨打
+
+    def set_sos_info_call(self,event,msg):
+        if sim.getStatus() != 1:#网络正常
+            self.sos_flag = 0
+            self.num = 0
+            return
+        if self.call_state != 0:
+            return
+        if self.sos_flag == 0:
+            self.sos_flag = 1
+        sos_flag = self.sos_flag
+        EventMesh.debug_log('voicecall sos_flag',sos_flag)
+        if sos_flag == 0 :
+            self.num = 0
+        else:
+            if len(self.sos_list) > 0:
+                # for list_t in self.sos_list:
+                #     tmp = list_t["phone"]
+                #     self.save_list.append(tmp)
+                    
+                self.num +=1
+                if len(self.sos_list) == 1:
+                    self.num_len = len(self.sos_list)*3#三次 1
+                elif len(self.sos_list) == 2:
+                    self.num_len = len(self.sos_list)*3 #1+2+1+2
+                elif len(self.sos_list) == 3:
+                    self.num_len = len(self.sos_list)*3 #1+3+5
+                # EventMesh.debug_log("number:{} number_len :{} num:{} num_len:{}".format(number,len(number),num,num_len))
+                if self.num > self.num_len :
+                    self.start_phone110112()
+                    EventMesh.debug_log("call phone!!!!!!!")
+                    self.sos_flag = 0
+                    self.num = 0
+                    self.num_len = 0
+                else:
+                    EventMesh.debug_log("self.num:{} self.num_len :{}".format(self.num,self.num_len))
+
+                    if len(self.sos_list) == 1:
+                        if len(self.sos_list[0]["phone"]) != 0:
+                            EventMesh.publish("call_out_cb", self.sos_list[0]["phone"]) 
+                            # EventMesh.publish("set_callnumer_cb",self.sos_list[0]["pnone"])
+                            EventMesh.debug_log("phone 1 {}".format(self.sos_list[0]["phone"]))
+                    elif len(self.sos_list) == 2:
+                        # 1 2 
+                        # 3 4 
+                        # 5 6
+                        if self.num == 1 or self.num == 3 or self.num == 5: #1 2 3 4 5 
+                            if len(self.sos_list[0]) != 0:
+                                EventMesh.debug_log("phone 2 {}".format(self.sos_list[0]["phone"]))
+                                EventMesh.publish("call_out_cb", self.sos_list[0]["phone"]) 
+                                # EventMesh.publish("set_callnumer_cb",self.sos_list[1]["pnone"])
+                        elif self.num == 2 or self.num == 4 or self.num == 6:
+                            if len(self.sos_list[1]) != 0:
+                                EventMesh.debug_log("phone 3 {}".format(self.sos_list[1]["phone"]))
+                                EventMesh.publish("call_out_cb", self.sos_list[1]["phone"]) 
+                                # EventMesh.publish("set_callnumer_cb",self.sos_list[0]["pnone"])
+                    elif len(self.sos_list) == 3:
+                        # 1 2 3 
+                        # 4 5 6 
+                        # 7 8 9 
+                        if self.num == 1 or self.num == 4 or self.num == 7:
+                            if len(self.sos_list[0]) != 0:
+                                EventMesh.publish("call_out_cb", self.sos_list[0]["phone"]) 
+                                # EventMesh.publish("set_callnumer_cb",self.sos_list[0]["phone"])
+                                EventMesh.debug_log("phone 4 {}".format(self.sos_list[0]["phone"]))
+                        elif self.num == 2 or self.num == 5 or self.num == 8:
+                            if len(self.sos_list[1]) != 0:
+                                EventMesh.debug_log("phone 5 {}".format(self.sos_list[1]["phone"]))
+                                EventMesh.publish("call_out_cb", self.sos_list[1]["phone"]) 
+                                # EventMesh.publish("set_callnumer_cb",self.sos_list[2]["phone"])
+                        elif self.num == 3 or self.num == 6 or self.num == 9:
+                            if len(self.sos_list[2]) != 0:
+                                EventMesh.debug_log("phone 6 {}".format(self.sos_list[2]["phone"]))
+                                EventMesh.publish("call_out_cb", self.sos_list[2]["phone"]) 
+                                # EventMesh.publish("set_callnumer_cb",self.sos_list[0]["phone"])
+            else: #清除表示
+                self.num=0
+                self.num_len = 0
+                self.sos_flag = 0
+                #未设置号码
+
+    def voice_callback(self,args):
+        EventMesh.debug_log('111test voicecall iinfo:{}'.format(args))
+        if args[0] == 10: #电话拨进来
+            self.sos_flag = 0
+            self.call_state = 1 
+        elif args[0] == 11: #已接听
+            self.call_state = 2
+            self.num=0 #不管有没有拨打sos都清除
+            self.num_len = 0
+            self.sos_flag = 0
+            self.close_call_timer()
+
+            EventMesh.debug_log('voicecall connected, PhoneNO.: ', args[6])
+
+        elif args[0] == 12: #电话挂断
+            if self.call_state == 2 or self.call_state == 1: #电话拨出去没有接听 就挂断
+                pass
+            else:
+               
+                EventMesh.debug_log('voicecall disconnect end !!!')
+                self.close_call_timer()
+                self.call_state = 0
+                self.set_sos_info_call(1,1)
+                pass
+            self.call_state = 0
+                #再次拨打下一个电话号码
+            EventMesh.debug_log('voicecall disconnect end')
+                
+
+        elif args[0] == 13: #
+            self.call_state = 7
+            EventMesh.debug_log('voicecall is waiting, PhoneNO.: ', args[6])
+        elif args[0] == 14: #电话拨出去
+            EventMesh.debug_log('voicecall dialing, PhoneNO.: ', args[6])
+            if self.sos_flag == 1:
+                self.call_state = 3 #当前是拨打sos号码标识
+            else:
+                self.call_state = 4
+                
+        elif args[0] == 15:
+            self.call_state = 5
+            EventMesh.debug_log('voicecall alerting, PhoneNO.: ', args[6])
+                    
+                
+        elif args[0] == 16:
+            self.call_state = 6
+            EventMesh.debug_log('voicecall holding, PhoneNO.: ', args[6])
+
+
+
+        
+try:   
+    import usr.ai_alarm as _schedule
+except Exception as e:
+    usys.print_exception(e)
+    import ai_alarm as _schedule
+DEFIEN_HR_REPORT_TIME = 3*60
+DEFIEN_LOCATION_REPORT_TIME = 60
+WEB_CONNECT_MAX_COUNT = 10 #默认重连次数
+class SockMangager(Abstract):
+    def __init__(self):
+        self.thread_buf_size = 16*1024
+        self.iot_web_send_queue = Queue(100)
+        self.iot_web_protoclo_recv_id=None
+        self.iot_protocol_client = None
+        self.connect_web_timer = osTimer() 
+        self.hr_report_timer = osTimer()
+        self.resolver = None
+        self.timerHr = 0
+        self.timerLocation = 0
+        self.timerSOS = 0
+        self.vbat_buf = []
+        self.network_state = 0
+        self.curr_battery_level = 0
+        self.socket_send_queue_id = None
+        self.bat_count = 0
+        self.minute_now_old = 0
+        self.old_minute = 0
+        self.is_alarm = 0
+        self.reconnect_count = 0 #连续重连次数 默认十次 不过就不重连了 等下一个心跳重连
+        self.schedule = _schedule.schedule()
+        self._1S_timer = osTimer()
+        self.timer_id = 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):
+        self.minute_now_old=0
+        EventMesh.subscribe("set_curr_battery_level",self.set_curr_battery_level)
+        EventMesh.subscribe("get_curr_battery_level",self.get_curr_battery_level)
+        EventMesh.subscribe("screen_get_battery",self.get_battery)
+        EventMesh.subscribe("CHANNEL_IOT_WEB_SEND",self.user_send)
+        EventMesh.subscribe("GET_IOT_PROTOCOL_CILENT",self.get_iot_protoclo_client)
+        EventMesh.subscribe("SEND_AUDIO_TO_IOT",self.send_audio_to_iot)
+        EventMesh.subscribe("open_websocket_timer",self.open_websocket_timer)
+        EventMesh.subscribe("close_websocket_timer",self.close_websocket_timer)
+        EventMesh.subscribe("connect_iot_websocket_cb",self.connect_iot_websocket_cb)
+        EventMesh.subscribe("set_play_new_voice_list",self.set_play_new_voice_list)
+        # import EventMesh
+        # EventMesh.publish("play_new_voice_list")
+        EventMesh.subscribe("play_new_voice_list",self.play_new_voice_list)
+        EventMesh.subscribe("update_play_new_voice_info",self.update_play_new_voice_info)
+        EventMesh.subscribe("send_bt_scan_list",self.send_bt_scan_list)
+        EventMesh.subscribe("save_bt_connect_list",self.save_bt_connect_list)
+        # count = 0
+        # while True:
+        #     count += 1
+        #     if count > 20 :
+        #         break
+        #     data = dataCall.getInfo(1, 0)
+        #     print("data call INFO {}".format(data))
+        #     if data[2][0]:
+        #         self.network_state = 1
+        #         break
+        #     print("web等待网络 {}...".format(count))
+        #     utime.sleep_ms(500)
+        self.connect_web_timer.start(5*1000,0,self.iot_web_connect_timerCb)
+        self.timerHr = 0
+        self.reconnect_count = 0
+        self.voice_id = ""
+        self.deviceReadState = ""
+        self.reconnect_count = 0
+        self.bt_connect_list = []
+        self.new_voice_list = [
+                {
+                "id":"1",
+                "url": "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3",
+                "size": 0,
+                "from": "user/dev",
+                "duration": 12,
+                "deviceId": "设备ID",
+                "userId": "用户ID",
+                "userReadState": "1",
+                "deviceReadState": "1",
+                "md5": "md5",
+                "fileName": "文件名"
+                },
+                {
+                "id":"2",
+                "url": "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3",
+                "size": 0,
+                "from": "user/dev",
+                "duration": 12,
+                "deviceId": "设备ID",
+                "userId": "用户ID",
+                "userReadState": "1",
+                "deviceReadState": "1",
+                "md5": "md5",
+                "fileName": "文件名"
+                },
+                {
+                "id":"3",
+                "url": "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3",
+                "size": 0,
+                "from": "user/dev",
+                "duration": 12,
+                "deviceId": "设备ID",
+                "userId": "用户ID",
+                "userReadState": "1",
+                "deviceReadState": "1",
+                "md5": "md5",
+                "fileName": "文件名"
+                },
+                {
+                "id":"4",
+                "url": "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3",
+                "size": 0,
+                "from": "user/dev",
+                "duration": 12,
+                "deviceId": "设备ID",
+                "userId": "用户ID",
+                "userReadState": "1",
+                "deviceReadState": "1",
+                "md5": "md5",
+                "fileName": "文件名"
+                }
+            ]
+    def save_bt_connect_list(self,event,msg):
+        data = {"event":"bt_connect_single","data":{"name":"yeiwyei","mac":"89:89:78:78:98:67"}}
+        try:
+            data = msg["data"]
+            mac = data["mac"]
+            need_save = 0
+            for i,_alarm in enumerate(self.bt_connect_list):
+                mac_tmp = _alarm["mac"]
+
+                if mac_tmp == mac:
+                    need_save = 1
+                    break
+                self.bt_connect_list[i]["state"] ="disconnected"
+
+            if need_save == 0: #列表里面没有才需要保存
+                self.bt_connect_list.append(data)
+
+        except Exception as e:
+            print("json数据不完整:self.recv_bt_connect_record_list")
+            usys.print_exception(e)
+        pass
+    def set_play_new_voice_list(self,event,msg):
+        self.new_voice_list = msg
+        pass
+
+    def play_new_voice_list(self,event,msg):
+        # {
+        #   "id":"语音ID"
+        #   "url": "音频地址",
+        #   "size": 0大小,kb,
+        #   "from": "user/dev",
+        #   "duration": 12 秒,
+        #   "deviceId": "设备ID",
+        #   "userId": "用户ID",
+        #   "userReadState": "0/1阅读状态",
+        #   "deviceReadState": "0/1阅读状态",
+        #   "md5": "md5",
+        #   "fileName": "文件名"
+        # }
+        if len(self.new_voice_list) != 0:
+            print("play_new_voice_list")
+            for i,data in enumerate(self.new_voice_list):
+                print("play_new_voice_list:{}".format(data))
+                self.voice_index = i
+                self.voice_id = data["id"]
+                url = data["url"]
+                # url = "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3"
+                EventMesh.publish("play_new_voice",[url,1])
+                self.new_voice_list.pop(i)
+                break
+            pass
+    def update_play_new_voice_info(self,event,msg): #更新播放语音留言信息
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        put_voice_msg_state = {
+            "cmd":"put_voice_msg_state",
+            "ts":time_tmp,
+            "msg":"修改语音消息阅读状态",
+            "data":self.voice_id
+        }
+        
+        EventMesh.publish(WEB_CMD_ENUM.PUT_VOICE_MSG_STATE_S,put_voice_msg_state)
+        pass
+    
+    def send_bt_scan_list(self,event,msg):
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        try:
+            print("type:{}".format(msg))
+            json_load = ujson.dumps(msg)
+            data = msg["data"]
+            bt_scan_rest ={
+                "cmd":"bt_scan_rest",
+                "ts":time_tmp,
+                "msg":"上报扫描列表",
+                "data":data
+            }
+            EventMesh.publish(WEB_CMD_ENUM.BT_SCAN_REST_S_CMD,bt_scan_rest)
+        except Exception as e:
+            usys.print_exception(e)
+        pass
+    
+    def send_audio_to_iot(self,event,msg):
+        send_data = b''
+        send_data = protocol_audio_playload_data(msg[0],msg[1])
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+        pass
+    
+    def all_states_zero(self,lst):
+
+        """检查列表中所有字典的state是否全为0"""
+        for item in lst:
+            # 检查是否存在state键且其值严格等于0(数字类型)
+            if 'state' not in item or item['state'] != 0:
+                return False
+        return True
+    def get_week_str(self,week):
+        week_str = ""
+        if week == 7:
+            week_str = "周日"
+        elif week == 1:
+            week_str = "周一"
+        elif week == 2:
+            week_str = "周二"
+        elif week == 3:
+            week_str = "周三"
+        elif week == 4:
+            week_str = "周四"
+        elif week == 5:
+            week_str = "周五"
+        elif week == 6:
+            week_str = "周六"
+        return week_str
+
+    def get_battery(self, event=None, msg=None):
+            """
+            获取电池事件,暂时没支持
+            :param event:
+            :param msg:
+            :return:
+            """
+
+            charge_state = '0'
+            usb_state = EventMesh.publish("GET_USB_STATE")
+            if usb_state == None:
+                usb_state = 0
+
+            if  usb_state == 1:
+                charge_state = '1'
+            else:
+                charge_state = '0'
+
+            #temp = Power.getVbatt()
+            temp = EventMesh.publish("get_curr_battery_level")
+            vbat = EventMesh.publish("get_battery",temp)
+            if vbat == None:
+                vbat = 100
+            # EventMesh.debug_log("vbat",vbat)
+            # if temp != None :
+            #     if temp <= 3505:
+            #         vbat = 0 
+            #     elif temp <= 3699:
+            #         vbat = 20 #"E:/vbat_20.jpg"
+            #     elif temp <= 3772:
+            #         vbat = 40 #"E:/vbat_40.jpg"
+            #     elif temp <= 3882:
+            #         vbat = 60 #"E:/vbat_60.jpg"
+            #     elif temp <= 4070:
+            #         vbat = 80 #"E:/vbat_80.jpg"
+            #     elif temp <= 4200:
+            #         vbat = 90 #
+            #     else:
+            #         vbat = 100 #"E:/vbat_100.jpg"
+            # else:
+            #     vbat = 100
+
+            result = [charge_state, vbat]
+
+            return result
+    def set_curr_battery_level(self, event=None, msg=None):
+        self.curr_battery_level = msg
+        
+    def get_curr_battery_level(self, event=None, msg=None):
+        return self.curr_battery_level
+    
+    def initialization(self, *args):
+        pass
+        #EventMesh.debug_log("ProtoCol:{}".format(self.TYPE + "_SEND"))
+    def connect_iot_websocket_cb(self,event,msg):
+        self.connect_iot_websocket()
+    def add_support_resolver(self, resolver):
+        self.resolver = resolver
+
+    def hr_report_event_cb(self, *args, **kwargs):
+        """电池平均值"""
+        temp = Power.getVbatt()
+        if self.bat_count < 10:
+            self.vbat_buf.append(temp)
+            self.bat_count += 1
+        else:
+            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_schedule_open")#读取闹钟数组
+        EventMesh.publish("AI_alarm_start") #检查是否有闹钟需要提醒
+        EventMesh.publish("AI_schedule_open")#检查日程是否需要提醒
+        # 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})  
+        self.timerHr+=1
+        if self.timerHr >= DEFIEN_HR_REPORT_TIME:
+            self.timerHr= 0
+            self.reconnect_count = 0
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.hr_report_publish_event,"data":0}) 
+
+        locate_duration_c = EventMesh.publish("get_storage_config","locate_duration_time") #获取定位频率
+        if locate_duration_c == None:
+            self.timerLocation = 0
+        else:
+            if locate_duration_c != 0:
+                self.timerLocation+=1
+                if self.timerLocation >= locate_duration_c:
+                    self.timerLocation= 0
+                    print("timerLocation")
+                    EventMesh.publish(constants.EVENT.START_LOCATION,WEB_CMD_ENUM.POST_LOCATION_S_CMD) #定位上报
+
+        self.timerSOS+=1
+        if self.timerSOS >= DEFIEN_LOCATION_REPORT_TIME:
+            self.timerSOS= 0
+            print("timerSOS")
+            date_tmp = utime.localtime()
+            time_tmp = utime.mktime(date_tmp)
+            get_new_voice_msg = {
+                "cmd":"get_new_voice_msg",
+                "ts":time_tmp,
+                "msg":"请求未读的语音消息列表",
+                "data":None
+            }
+        
+            send_data = b''
+            send_data = protocol_send_total_data(get_new_voice_msg)
+            print("send send_data{}".format(send_data))
+            EventMesh.publish(WEB_CMD_ENUM.GET_NEW_VOICE_MSG_S,send_data)
+            
+            # alarm_config=EventMesh.publish("GET_IOT_WEB_SEND_CMD",WEB_CMD_ENUM.POST_ALARM_S_CMD)
+            # print("alarm_config{}".format(alarm_config))
+            # EventMesh.publish(WEB_CMD_ENUM.POST_ALARM_S_CMD,alarm_config)
+
+            # HR_DATA=EventMesh.publish("GET_IOT_WEB_SEND_CMD",WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD)
+            # print("HR_DATA{}".format(HR_DATA))
+            # EventMesh.publish(WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD,HR_DATA) #上报设备状态
+
+            # EventMesh.publish(constants.EVENT.START_LOCATION,WEB_CMD_ENUM.POST_SOS_S_CMD) #sos上报
+
+        # http://220.160.104.34:30800/ws-bus/test/voice-record/876226211472149?state=1,
+        # http://220.160.104.34:30800/ws-bus/test/876226211472149?testType=alarmList
+    def hr_report_publish_event(self,data):
+        
+        HR_DATA = EventMesh.publish("GET_IOT_WEB_SEND_CMD",WEB_CMD_ENUM.HR_S_CMD)
+        print("HR_DATA{}".format(HR_DATA))
+        EventMesh.publish(WEB_CMD_ENUM.HR_S_CMD,HR_DATA)
+        pass
+
+    def iot_web_connect_timerCb(self,*argc):
+        self.connect_iot_websocket()
+
+    def connect_iot_websocket(self):
+        if EventMesh.publish("get_voice_record_flag") == 1:
+            EventMesh.publish("stop_voice_record")
+        print("connect_iot_websocket !!!!")
+        self.iot_close_web_therad()
+        
+        if sim.getStatus() != 1 or self.start_voice_flag == 1:#网络正常
+            return
+        
+       
+        if self.reconnect_count >= WEB_CONNECT_MAX_COUNT: #重连次数大于10次不在进重连只有下发心跳才重新连接
+            return
+        token = EventMesh.publish("get_dev_token")
+
+        print("token:{}".format(token))
+        token = "957119d6b67b89dc1bc533d2e0c058d559"
+        # token = "951b74498eabe241e8a8c644a4f07531ef"
+
+        try:
+            if token != None:
+                url_t = "ws://220.160.104.34:30800/ws-hub/dev/v1?qp-dt={}".format(token)
+                try:
+                    self.iot_protocol_client=uwebsocket.Client.connect(url_t, debug=True)
+                except Exception as e:
+                    print("再次连接")
+                    self.iot_protocol_client=uwebsocket.Client.connect(url_t, debug=True)
+
+
+                if self.iot_protocol_client != None:
+                    _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_web_protoclo_recv_id = _thread.start_new_thread(self.iot_protocol_recv, ())
+                    _thread.stack_size(8*1024)
+                else:
+                    print("self.iot_protocol_client init!!!!!!!!!")
+                    self.reconnect_count+=1
+                    # EventMesh.publish("connect_iot_websocket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket}) #self.connect_iot_websocket()
+                    return 
+
+                if self.iot_protocol_client != None:
+                    self.start_voice_flag = 1
+                else:
+                    self.start_voice_flag = 0
+                    
+                print("self.iot_protocol_client %d self.start_voice_flag:%d",self.iot_protocol_client,self.start_voice_flag)
+                if self.iot_protocol_client != None:
+                    if self.timer_id == 0:
+                        self.hr_report_timer.start(1000, 1, self.hr_report_event_cb)
+                        self.timer_id=1
+                
+        except Exception as e:   
+            self.iot_protocol_client = None
+            print("connect_iot_websocket error")
+    
+    def open_websocket_timer(self,event,msg):
+        self.VC_pingping_timerout = 0
+        # self._1S_timer.start(500,1,self._1S_timer_cb)
+    
+    def close_websocket_timer(self,event,msg):
+        self._1S_timer.stop()
+
+    def _1S_timer_cb(self,*argc):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_}) 
+
+    def _1S_timer_cb_(self): 
+        self.iot_web_send_queue.put("ping") 
+        
+    def socket_send_queue_thread(self):
+        while True:
+            data = self.iot_web_send_queue.get()
+            EventMesh.debug_log("websocket:send data1 len:{}".format(len(data)))
+            if data != None:
+                try:
+                    EventMesh.debug_log("websocket:send data1 len:{} {}".format(len(data),self.iot_protocol_client))    
+                    if self.iot_protocol_client != None:
+                        self.iot_protocol_client.send(data)
+                        self.reconnect_count = 0
+                    else:
+                        self.reconnect_count+=1
+                        # EventMesh.publish("connect_iot_websocket_cb")
+                        EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket})
+                    EventMesh.debug_log("websocket:send data2 len:{}".format(len(data)))    
+                except Exception as e:
+                    EventMesh.debug_log("websocket:send error") 
+                    self.reconnect_count+=1
+                    # EventMesh.publish("connect_iot_websocket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket})
+                    break
+            utime.sleep_ms(10)
+             
+
+    def iot_protocol_recv(self):
+        while True:
+            # 死循环接收数据
+            try:
+                recv_data = self.iot_protocol_client.recv()
+                print("recv_data = {}".format(len(recv_data)))
+                if recv_data == "websocket close":
+                    # 服务器关闭连接或客户端关闭连接
+                    print("对端 服务器强制关闭 cli close")
+                    self.reconnect_count+=1
+                    # EventMesh.publish("connect_iot_websocket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket}) 
+                    break
+                else:
+                    if len(recv_data) != 0:
+                        self.reconnect_count = 0
+                        self.resolver.handler(recv_data)
+                
+            except Exception as e:
+                print("cli break")
+                self.reconnect_count+=1
+                # EventMesh.publish("connect_iot_websocket_cb")
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket}) 
+                break
+            utime.sleep_ms(10)
+        self.iot_web_protoclo_recv_id =None
+
+    def iot_web_send_queue_close(self):
+        if self.socket_send_queue_id != None:
+            if self.iot_web_send_queue.empty()!=True:
+                self.iot_web_send_queue.clear()
+            try:
+                _thread.stop_thread(self.socket_send_queue_id)
+            except Exception as e:
+                print("iot_web_protoclo_recv_id !!!!!!!!")
+        print("iot_web_protoclo_recv_id 1111!!!!!!!!")
+        self.socket_send_queue_id = None
+    
+    def iot_web_protoclo_recv_close_therad(self):
+        if self.iot_web_protoclo_recv_id != None:
+            try:
+                _thread.stop_thread(self.iot_web_protoclo_recv_id)
+            except Exception as e:
+                print("self.iot_web_protoclo_recv_id !!!!!!!!")
+        self.iot_web_protoclo_recv_id = None
+        if self.iot_protocol_client != None:
+            try:
+                print("关闭websocke")
+                self.iot_protocol_client.close()
+            except Exception as e:   
+                print("关闭websocke失败")
+        self.iot_protocol_client = None
+        
+
+        
+    def iot_close_web_therad(self):
+        try:
+            self.iot_web_send_queue_close()
+            print("iot_web_send_queue_close sucess!!!!!!!!")
+        except Exception as e:
+            print("iot_web_send_queue_close error!!!!!!!!")
+
+        try:
+            self.iot_web_protoclo_recv_close_therad()
+            print("iot_web_protoclo_recv_close_therad sucess!!!!!!!!")
+        except Exception as e:
+            print("iot_web_protoclo_recv_close_therad error!!!!!!!!")
+        self.start_voice_flag = 0
+        print("iot_close_web_therad")
+    
+    def get_iot_protoclo_client(self,event,msg):
+        return self.iot_protocol_client
+    def user_send(self,event,data):
+        # EventMesh.debug_log("TCP:send data:{}".format(msg))
+        # EventMesh.debug_log("TCP:send data:{}".format(msg))
+        sim_state = sim.getStatus() 
+        if sim.getStatus() != 1:#网络不正常
+            print("无 sim卡")
+            return
+        else :
+            try:
+                if self.start_voice_flag == 0: #如果关闭了就需要重新再
+                    self.reconnect_count+=1
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket}) 
+
+                self.iot_web_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) 
+                
+        return
+        sim_state = sim.getStatus() 
+        if sim_state != 1 or self.network_state == 0: #没sim,则不发送 ,没联网
+            return
+        else :
+            try:
+                if self.iot_protocol_client != 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_websocket})
+
+            except Exception as e:   
+                print("senc data err reconnect{}".format(data))
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket})
+                
+    def iot_protocol_send_cb(self,data):
+        try:
+            if data != None:
+                print("websocket connect success:{} self.iot_protocol_client:{}".format(data,self.iot_protocol_client))
+                if self.iot_protocol_client != None:
+                    self.iot_protocol_client.send(data)
+                    self.reconnect_count = 0
+                    print("websocket send success")
+                else:
+                    print("reconnect2 {}".format(data))
+                    # EventMesh.publish("connect_iot_websocket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket})
+        except Exception as e:
+            print("发送失败 重新连接")
+            self.reconnect_count+=1
+            # EventMesh.publish("connect_iot_websocket_cb")
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_websocket})
+   
+
+
+
+class NetManager(Abstract):
+    THRESHOLD = 10
+
+    def __init__(self):
+        self.__data_call = dataCall
+        self.__net = net
+        self.check_net = checkNet.CheckNetwork("QuecPython_Helios_Framework", "this latest version")
+        EventMesh.subscribe("get_network_state", self.get_network_state)
+        self.network_state = 0
+
+    def post_processor_after_instantiation(self, *args, **kwargs):
+        count = 0
+        while True:
+            count += 1
+            if count > 5 :
+                return
+            data = dataCall.getInfo(1, 0)
+            EventMesh.debug_log("data call INFO {}".format(data))
+            if data[2][0]:
+                self.network_state = 1
+                break
+            utime.sleep(1)
+        self.__data_call.start(2, 0, "", "", "", 0)
+        self.__data_call.setCallback(self.__datacall_cb)
+
+    def __datacall_cb(self, args):
+        pdp = args[0]
+        nw_sta = args[1]
+        if nw_sta == 1:
+            self.network_state = 1
+            EventMesh.debug_log("*** network %d connected! ***" % pdp)
+
+        else:
+            self.network_state = 0
+            EventMesh.debug_log("*** network %d not connected! ***" % pdp)
+           
+    def get_network_state(self, topic, msg):
+        return self.network_state 
+
+
+class ProtoCol(Abstract):
+    TYPE = ""
+    HEADER = "#@{}@#;"
+    SEPARATOR = ";"
+    END = ";" + chr(0x01)
+    #PID = "SZKW"
+    #PID = "qAELPTKmFanR4RHe"
+    md5_key = ''
+    PID = ''
+
+    def __init__(self):
+        pass
+
+    def initialization(self,*args):
+        EventMesh.subscribe(self.TYPE+"_S", self.handler)
+        EventMesh.subscribe(self.TYPE+"_R", self.handler)
+        pass
+
+    def handler(self, event, msg):
+        print("handler {}".format(event))
+        if event.endswith("_S"):
+            self.send(event, msg)
+        else:
+            self.recv(event, msg)
+
+    def send(self, event, msg):
+       
+        pass
+
+    def recv(self, event, msg):
+        pass
+#上报心跳
+class IOTWeb_HRProtoCol(ProtoCol):
+    """post_heart_beat"""
+    TYPE = "post_heart_beat"
+
+    def send(self, event, msg):
+        print("send hr{}".format(msg))
+        # 通过websocket发送到服务器端
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: 心跳成功
+        @param msg: 接收到的下行数据
+        """
+        print("recv hr{}".format(msg))
+#定位周期
+class IOTWeb_locatedurationProtoCol(ProtoCol):
+    """locate_duration"""
+    TYPE = "locate_duration"
+
+    def send(self, event, msg):
+        print("send locate_duration{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        locatio = {
+            "cmd":"dispatch_rest",
+            "ts":int(time_tmp),
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"locate_duration",
+                "rest":"success",
+                "msg":"收到定位周期指令"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(locatio)
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:定位周期
+        @param msg: 接收到的下行数据
+        """
+        # locate_now = {
+        #     "cmd":"locate_duration",
+        #     "ts":1738283829,
+        #     "msg":"下发定位周期",
+        #     "data":300,0表示关
+        # }
+        if "data" in msg:
+            locate_duration_time = msg["data"]
+            EventMesh.publish("set_storage_config",["locate_duration_time",int(locate_duration_time)])
+            locate_duration_c = EventMesh.publish("get_storage_config","locate_duration_time")
+            print("locate_duration_c:{}".format(locate_duration_c))
+        
+#上报SOS告警信息
+class IOTWeb_post_sosProtoCol(ProtoCol):
+    """post_sos"""
+    TYPE = "post_sos"
+
+    def send(self, event, msg):
+        print("send post_sos{}".format(msg))
+        # 通过websocket发送到服务器端
+       
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:msg
+        @param msg: 接收到的下行数据
+        """
+        # locate_now = {
+        #     "cmd":"locate_duration",
+        #     "ts":1738283829,
+        #     "msg":"下发定位周期",
+        #     "data":300,0表示关
+        # }
+        print("recv post_sos{}".format(msg))
+
+#上报设备状态    
+class IOTWeb_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_WEB_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 IOTWeb_post_alarmProtoCol(ProtoCol):
+    """post_alarm"""
+    TYPE = "post_alarm"
+
+    def send(self, event, msg):
+        print("send post_alarm{}".format(msg))
+        # 通过websocket发送到服务器端
+       
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        print("send send_data{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:post_alarm
+        @param msg: 接收到的下行数据
+        """
+        print("recv post_alarm{}".format(msg))
+       
+#查找设备
+class IOTWeb_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(msg))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:定位信息下发
+        @param msg: 接收到的下行数据
+        """
+        EventMesh.publish("set_sos_info_call")
+        print("recv find_device{}".format(msg))
+        EventMesh.publish(WEB_CMD_ENUM.FIND_DEVCE_S_CMD,None)
+
+#立即定位
+class IOTWeb_LocateNowProtoCol(ProtoCol):
+    """locate_now"""
+    TYPE = "locate_now"
+    def send(self, event, msg):
+        print("send locate_now{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        locate_now = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"locate_now",
+                "rest":"success",
+                "msg":"收到立即定位指令"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(locate_now)
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:立即定位
+        @param msg: 接收到的下行数据
+        """
+        
+        EventMesh.publish(WEB_CMD_ENUM.LOCATION_NOW_S_CMD,None)
+        print("recv locate_now{}".format(msg))
+        EventMesh.publish(constants.EVENT.START_LOCATION,WEB_CMD_ENUM.POST_LOCATION_S_CMD) #开始定位 定位完之后上报定位数据
+
+
+#上报定位信息 
+class IOTWeb_post_locationProtoCol(ProtoCol):
+    """post_location"""
+    TYPE = "post_location"
+
+    def send(self, event, msg):
+        # 通过websocket发送到服务器端
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        print("send_data post_location{}".format(msg))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:定位信息下发
+        @param msg: 接收到的下行数据
+        """
+        print("recv post_location{}".format(msg))
+#闹钟列表
+class IOTWeb_alarm_listProtoCol(ProtoCol):
+    """alarm_list"""
+    TYPE = "alarm_list"
+
+    def send(self, event, msg):
+        print("send alarm_list {}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        rest = "error"
+        if msg == 1:
+            rest = "success"
+        alarm_list ={
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"alarm_list",
+                "rest":rest,
+                "msg":"闹钟配置成功."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(alarm_list)
+        print("send_data alarm_list {}".format(msg))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发闹钟配置
+        @param msg: 接收到的下行数据
+        """
+        # 定义要添加的新元素
+        # new_item = {'time': '11:30','index': 1}
+        # data = [{"index":1,"name":"hihihi1"},{"index":2,"name":"hihihi2"},{"index":0,"name":"hihihi0"}]
+        # len_t = len(data)
+        # j = 0
+        # for i in range(len_t):
+        #     if data[j]['index'] == 1:
+        #         removed_item = data.pop(j)
+        #         print(data)
+        #         j=0
+        #         continue
+        #     j+=1
+        #     len_t = len(data)
+        #     print(len_t)
+        # for i in range(len(data)):
+        #     data[i]["index"] = i
+   
+        # url = http://220.160.104.34:30800/ws-bus/test/voice-record/876226211472149?state=1
+            # url = http://220.160.104.34:30800/ws-bus/test/876226211472149?testType = alarmList
+
+        alarm_list=[]
+        ret = 1
+        if "data" in msg:
+            data = msg["data"]
+            if isinstance(data,list) == True:
+                for i in range(len(data)):
+                    data_list = data[i]
+                    data_list["index"] = i
+                    print("data_list:{}".format(data_list))
+                    alarm_list.append(data_list)
+                alarm_list.sort(key=lambda x: x['index'])
+                EventMesh.publish("set_storage_config",["alarm_list",alarm_list])
+                alarm_list = EventMesh.publish("get_storage_config","alarm_list")
+                print("alarm_list:{}".format(alarm_list))
+            else:
+                ret = 0
+            
+        EventMesh.publish(WEB_CMD_ENUM.ALARM_LIST_S_CMD,ret)
+
+
+#闹钟配置下发
+
+class IOTWeb_alarm_configProtoCol(ProtoCol):
+    """alarm_config"""
+    TYPE = "alarm_config"
+
+    def send(self, event, msg):
+        print("send locafind_devicetion{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        alarm_config ={
+            "cmd":"dispatch_rest",
+            "ts":int(time_tmp),
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"alarm_config",
+                "rest":"success",
+                "msg":"闹钟配置成功."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(alarm_config)
+        print("send_data alarm_config{}".format(msg))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发闹钟配置
+        @param msg: 接收到的下行数据
+        """
+        print("recv alarm_config{}".format(msg))
+        EventMesh.publish(WEB_CMD_ENUM.ALARM_CONFIG_S_CMD,None)
+
+#SOS联系人下发
+class IOTWeb_sos_listProtoCol(ProtoCol):
+    """sos_list"""
+    TYPE = "sos_list"
+
+    def send(self, event, msg):
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        sos_list ={
+            "cmd":"dispatch_rest",
+            "ts":int(time_tmp),
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"sos_list",
+                "rest":"success",
+                "msg":"收到SOS联系人列表."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(sos_list)
+        print("send_data sos_list{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发sos列表
+        @param msg: 接收到的下行数据
+        """
+        #{'msg': 'SOS', 'data': [{'name': '0', 'createTime': 1754031896067, 'updateTime': 1754031896067, 'phone': '12345678900', 'id': '1754031896067', 'deviceId': '876226211472149'}, 
+        # {'name': '1', 'createTime': 1754031896067, 'updateTime': 1754031896067, 'phone': '12345678901', 'id': '1754031896067', 'deviceId': '876226211472149'},
+        #  {'name': '2', 'createTime': 1754031896067, 'updateTime': 1754031896067, 'phone': '12345678902', 'id': '1754031896067', 'deviceId': '876226211472149'},
+        #  {'name': '3', 'createTime': 1754031896067, 'updateTime': 1754031896067, 'phone': '12345678903', 'id': '1754031896067', 'deviceId': '876226211472149'},
+        #  {'name': '4', 'createTime': 1754031896067, 'updateTime': 1754031896067, 'phone': '12345678904', 'id': '1754031896067', 'deviceId': '876226211472149'}],
+        #  'ts': 1754031896067, 'cmd': 'sos_list'}
+        print("recv sos_list{}".format(msg))
+        sos_list = []
+        if "data" in msg:
+            data = msg["data"]
+            if isinstance(data,list) == True:
+                sos_list_len = len(data)
+                if sos_list_len >= 3:
+                    sos_list_len = 3
+                for i in range(sos_list_len):
+                    save_data = {}
+                    # EventMesh.publish("set_storage_config",["SOS_NUMBER{}".format(i+1),data[i+1]])
+                    # sos_list.append(str(data[i+1]))
+                    save_data["index"] = i
+                    save_data["name"] = data[i]["name"]
+                    save_data["phone"] = data[i]["phone"]
+                    sos_list.append(save_data)
+                    # EventMesh.publish("set_storage_config",["sos_list",sos_list])
+            sos_list.sort(key=lambda x: x['index'])
+            EventMesh.publish("set_storage_config",["sos_list",sos_list])
+            read_soslist = EventMesh.publish("get_storage_config","sos_list")
+            print(read_soslist)
+            EventMesh.publish(WEB_CMD_ENUM.SOS_LIST_S_CMD,None)
+
+#闹钟铃声下发
+class IOTWeb_volumeProtoCol(ProtoCol):
+    """volume"""
+    TYPE = "volume"
+
+    def send(self, event, msg):
+        print("send volume{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        volume = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"volume",
+                "rest":"success",
+                "msg":"收到音量设置."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(volume)
+        print("send_data volume{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发volume
+        @param msg: 接收到的下行数据
+        """
+        if "data" in msg:
+            r_volume = msg["data"]
+            print("recv volume{} type:{}".format(r_volume,type(msg)))
+            EventMesh.publish("set_storage_config",["volume",int(r_volume)])
+        vloum = EventMesh.publish("get_storage_config","volume")
+        print(vloum)
+        EventMesh.publish(WEB_CMD_ENUM.VOLUME_S_CMD,None)
+#下发SOS配置
+class IOTWeb_sos_configProtoCol(ProtoCol):
+    """sos_config"""
+    TYPE = "sos_config"
+
+    def send(self, event, msg):
+        print("send sos_config{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        sos_config = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"sos_config",
+                "rest":"success",
+                "msg":"SOS配置成功."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(sos_config)
+        print("send_data sos_config{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发sos_config
+        @param msg: 接收到的下行数据
+        """
+        print("recv sos_config{}".format(msg))
+        if "data" in msg:
+            sos_config = msg["data"]
+            print("recv sos_config{} type:{}".format(sos_config,type(msg)))
+            EventMesh.publish("set_storage_config",["sos_config",sos_config])
+        sos_config = EventMesh.publish("get_storage_config","sos_config")
+        print("sos_config:{} type:{}".format(sos_config,sos_config["enable110"]))
+        EventMesh.publish(WEB_CMD_ENUM.SOS_CONFIG_S_CMD,None)
+#闹钟铃声获取
+
+class IOTWeb_get_ringtoneProtoCol(ProtoCol):
+    """get_ringtone"""
+    TYPE = "get_ringtone"
+
+    def send(self, event, msg):
+        print("send get_ringtone{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        get_ringtone ={
+            "cmd":"get_ringtone",
+            "ts":time_tmp,
+            "msg":"请求下发铃声列表",
+            "data":None
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(get_ringtone)
+        print("send_data get_ringtone{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发get_ringtone
+        @param msg: 接收到的下行数据
+        """
+        print("recv get_ringtone{}".format(msg))
+
+#闹钟铃声列表
+class IOTWeb_ringtone_listProtoCol(ProtoCol):
+    """ringtone_list"""
+    TYPE = "ringtone_list"
+
+    def send(self, event, msg):
+        print("send ringtone_list{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        ringtone_list ={
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"ringtone_list",
+                "rest":"success|error",
+                "msg":"收到闹钟铃声列表."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(ringtone_list)
+        print("send_data ringtone_list{}".format(msg))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发ringtone_list
+        @param msg: 接收到的下行数据
+        """
+        print("recv ringtone_list{}".format(msg))
+
+
+#下发静默录音
+class IOTWeb_voice_recordProtoCol(ProtoCol):
+    """voice_record"""
+    TYPE = "voice_record"
+    start_ai = 0
+    def send(self, event, msg):
+        print("send voice_record{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        s_rest = "0"
+        s_msg = "停止录音."
+        if msg == "1":
+            print("设备允许录音")
+            s_rest = "1"
+            s_msg = "开始录音."
+        
+        voice_record = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"voice_record",
+                "rest":s_rest,
+                "msg":s_msg
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(voice_record)
+        print("send_data voice_record{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发voice_record
+        @param msg: 接收到的下行数据
+        """
+        print("recv voice_record{}".format(msg))
+        if "data" in msg:
+            data = msg["data"]
+            s_rest = "0"
+            if data == "0":
+                s_rest = "0"
+                EventMesh.publish(WEB_CMD_ENUM.VOICE_RECORD_S_CMD,s_rest)
+                EventMesh.publish("stop_voice_record")
+                print("停止录音")
+                
+            elif data == "1":
+                s_rest = "1"
+                EventMesh.publish(WEB_CMD_ENUM.VOICE_RECORD_S_CMD,s_rest)
+                EventMesh.publish("start_voice_record")
+                print("开始录音")
+        
+            
 
+#下发位子留言
+class IOTWeb_text_msgProtoCol(ProtoCol):
+    """text_msg"""
+    TYPE = "text_msg"
 
+    def send(self, event, msg):
+        print("send text_msg{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+
+        rest = "error"
+        if msg == 1:
+            rest = "success"
+        text_msg = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"text_msg",
+                "rest":rest,
+                "msg":"收到文本消息."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(text_msg)
+        print("send_data text_msg{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-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]
+    def recv(self, event, msg):
+        """
 
-        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)
-        
+        @param event:上行下发voice_record
+        @param msg: 接收到的下行数据
+        """
+        print("recv time_tmp{}".format(msg))
+        recv_state = 0
+        if "data" in msg:
+            play_tts_text = msg["data"]
+            try:
+                EventMesh.publish("play_tts",[play_tts_text,0])
+                recv_state = 1
+            except Exception as e:
+                print("下发文字留言出错了")
+        EventMesh.publish(WEB_CMD_ENUM.TEXT_MSG_S_CMD,recv_state)
         
-        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)
 
-        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)
+#下发日程    
+class IOTWeb_scheduleProtoCol(ProtoCol):
+    """schedule"""
+    TYPE = "schedule"
 
-        EventMesh.subscribe("set_deviceSecret",self.set_deviceSecret)
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        schedule = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"schedule",
+                "rest":"success",
+                "msg":"收到日程列表."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(schedule)
+        print("send_data schedule{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-        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()
+    def recv(self, event, msg):
+        """
 
-    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)
+        @param event:上行下发schedule
+        @param msg: 接收到的下行数据
+        """
+        #         {
+        #     "cmd":"text_msg",
+        #     "ts":1738283829,
+        #     "msg":"下发文本消息",
+        #     "data":"文本内容"
+        # }
+        print("recv time_tmp{}".format(msg))
+        # {
+        #     "cmd":"schedule",
+        #     "ts":1738283829,
+        #     "msg":"下发日程列表",
+        #     "data":[
+        #         "title":"日程名称",
+        #         "description":"提醒内容",
+        #         "repeat":1~4播报重复次数,
+        #         "date":"日期,yyyy-MM-dd",
+        #         "时间":"HH:mm"
+        #     ]
+        # }
+        schedule = []
+        if "data" in msg:
+            data = msg["data"]
+            for i,sh in enumerate(data):
+                sh["index"] = i
+                schedule.ap
+                schedule.append(sh)
+            schedule.sort(key=lambda x: x['index'])
+            EventMesh.publish("set_storage_config",["schedule",schedule])
+            schedule = EventMesh.publish("get_storage_config","schedule")
+            print(schedule)
+        EventMesh.publish(WEB_CMD_ENUM.SCHEDULE_S_CMD,None)
+#     
+class IOTWeb_new_voice_msgProtoCol(ProtoCol):
+    """new_voice_msg"""
+    TYPE = "new_voice_msg"
 
-    def add_support_resolver(self, resolver):
-        self.resolver = resolver
+    def send(self, event, msg):
+        print("send new_voice_msg{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        new_voice_msg = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"new_voice_msg",
+                "rest":"success",
+                "msg":"收到新语音消息指令."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(new_voice_msg)
+        print("send send_data{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
+        EventMesh.publish(WEB_CMD_ENUM.GET_NEW_VOICE_MSG_S,None)
+    def recv(self, event, msg):
+        """
 
-    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)
-        
-    def get_device_id(self,event,msg):
+        @param event:new_voice_msg
+        @param msg: 接收到的下行数据
+        """
+        EventMesh.publish(WEB_CMD_ENUM.NEW_VOICE_MSG_S,None)
 
-        return self.device_id
-    def set_device_key(self,event,msg):
-        self.device_key = str(msg)
-        return
-    def get_device_key(self,event,msg):
+        print("recv new_voice_msg{}".format(msg))
 
-        return self.device_key
-    
-    def set_product_key(self,event,msg):
-        self.product_key = str(msg)
-        
-    def get_product_key(self,event,msg):
+class IOTWeb_get_new_voice_msgProtoCol(ProtoCol):
+    """get_new_voice_msg"""
+    TYPE = "get_new_voice_msg"
 
-        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
-    
-    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
-        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]
+    def send(self, event, msg):
+        print("send get_new_voice_msg{}".format(msg))
+        # 通过websocket发送到服务器端
+        # date_tmp = utime.localtime()
+        # time_tmp = utime.mktime(date_tmp)
+        # get_new_voice_msg = {
+        #     "cmd":"get_new_voice_msg",
+        #     "ts":time_tmp,
+        #     "msg":"请求未读的语音消息列表",
+        #     "data":None
+        # }
+       
+        # send_data = b''
+        # send_data = protocol_send_total_data(get_new_voice_msg)
+        # print("send send_data{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",msg)
 
-                # 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 recv(self, event, msg):
+        """
 
-    def mqtt_recv_timer_cb(self, *args):
-        self.mqtt_clien_cb()
-        
+        @param event:get_new_voice_msg
+        @param msg: 接收到的下行数据
+        """
+        #  get_new_voice_msg = {
+        #     "cmd":"post_rest",
+        #     "ts":time_tmp,
+        #     "msg":"消息收到响应",
+        #     "data":{
+        #         "cmd":"get_new_voice_msg",
+        #         "rest":"success",
+        #         "msg":"收到请求新语音列表."
+        #     }
+        # }
+
+class IOTWeb_new_voice_msg_listProtoCol(ProtoCol):
+    """new_voice_msg_list"""
+    TYPE = "new_voice_msg_list"
 
+    def send(self, event, msg):
+        print("send new_voice_msg_list{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        new_voice_msg_list = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"new_voice_msg_list",
+                "rest":"success",
+                "msg":"收到新语音列表."
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(new_voice_msg_list)
+        print("send send_data{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
 
-    def mqtt_clien_cb(self):
-        if EventMesh.platform != "gewu":
-            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)
+    def recv(self, event, msg):
+        """
 
-                        self.client.subscribe(subscribe_msg,0)#订阅消息主题
+        @param event:new_voice_msg_list
+        @param msg: 接收到的下行数据
+        """
+        new_voice_msg_list = {
+            "cmd":"new_voice_msg_list",
+            "ts":1738283829,
+            "msg":"请求未读的语音消息列表",
+            "data":[
+                {
+                "id":"语音ID",
+                "url": "音频地址",
+                "size": 0,
+                "from": "user/dev",
+                "duration": 12,
+                "deviceId": "设备ID",
+                "userId": "用户ID",
+                "userReadState": "1",
+                "deviceReadState": "1",
+                "md5": "md5",
+                "fileName": "文件名"
+                }
+            ]
+        }
+        new_voice_list = []
+        if "data" in msg:
+            data = msg["data"]
+            for da in enumerate(data):
+                new_voice_list.append(da)
+
+        if len(new_voice_list) > 0:
+            pass
 
-                        
-                        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
+        EventMesh.publish("set_play_new_voice_list",new_voice_list)
+        EventMesh.publish("play_new_voice_list")
 
-                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
-                        
+        EventMesh.publish(WEB_CMD_ENUM.NEW_VOICE_MSG_LIST_S,None)
+        print("recv new_voice_msg_list{}".format(msg))
+class IOTWeb_put_voice_msg_stateProtoCol(ProtoCol):
+    """put_voice_msg_state"""
+    TYPE = "put_voice_msg_state"
 
-                    if mqtt_dev_connect != 0:#连接参数错误可能是deviceScrete出错重新获取
-                    
-                        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"
+    def send(self, event, msg):
+        print("send put_voice_msg_state{}".format(msg))
+        # 通过websocket发送到服务器端
+       
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        print("send send_data{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND",send_data)
 
-                        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主题内容
+    def recv(self, event, msg):
+        """
 
-                        print("Publish topic: /public/TEST/quecpython758, msg: my name is Quecpython")
+        @param event:put_voice_msg_state
+        @param msg: 接收到的下行数据
+        """
+        print("recv put_voice_msg_state{}".format(msg))
+#蓝牙开关
+class IOTWeb_switch_bt_stateProtoCol(ProtoCol):
+    """switch_bt_state"""
+    TYPE = "switch_bt_state"
 
-    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)
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        switch_bt_state = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"switch_bt_state",
+                "rest":"success",
+                "msg":"蓝牙已打开"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(switch_bt_state)
+        print("send_data switch_bt_state{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发switch_bt_state
+        @param msg: 接收到的下行数据
+        """
+        if "data" in msg:
+            data = msg["data"]
+            if data == "0":
+                EventMesh.publish("set_storage_config",["switch_bt_state","0"])
+                EventMesh.publish("send_ble_adv_switch","0")
+                pass
+            elif data == "1":
+                EventMesh.publish("set_storage_config",["switch_bt_state","1"])
+                EventMesh.publish("send_ble_adv_switch","1")
+                pass
+        print("recv switch_bt_state{}".format(msg))
         
-    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):#正常连击
-                if data != None:
-                    try:
-                        self.sock.send(data)
-                        EventMesh.debug_log("TCP:send data2 len:{}".format(len(data)))    
-                    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)
-                        break
-            else :#连接错误
-                EventMesh.debug_log("socket_send_queue_thread:ERROR:reconnect")
-                self.reconnect()
-            utime.sleep(1)
+        EventMesh.publish(WEB_CMD_ENUM.SWITCH_BT_STATE_S_CMD,None)
 
-    def send(self, topic, 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")
-            return
-        else :
-            try:
-                self.socket_send_queue.put(msg)
-            except Exception as e:   
-                EventMesh.debug_log("self.socket_send_queue.put:ERROR:")
-                usys.print_exception(e) 
-                # self.run_flag = False
+#蓝牙扫描
+class IOTWeb_bt_scanProtoCol(ProtoCol):
+    """bt_scan"""
+    TYPE = "bt_scan"
 
-    def recv(self):
-        data = b''
-        while True:
-            try:
-                r =  b''
-                r = self.sock.recv(1024*5)
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        s_msg = ""
+        if msg == "0":
+            s_msg = "开始扫描附近设备"
+        elif msg == "1":
+            s_msg = "停止扫描附近设备"
+        bt_scan = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"bt_scan",
+                "rest":"success",
+                "msg":s_msg
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(bt_scan)
+        print("send_data bt_scan{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-                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()
-                
-                data = b''
-                utime.sleep(2)
+    def recv(self, event, msg):
+        """
 
+        @param event:上行下发bt_scan
+        @param msg: 接收到的下行数据
+        """
+        # {
+        #     "cmd":"bt_scan",
+        #     "ts":1738283829,
+        #     "msg":"开始扫描附近设备/停止扫描附近设备",
+        #     "data":"0/1"
+        # }
+        s_ret = "1"
+        if "data" in msg:
+            data = msg["data"]
+            if data == "1":
+                s_ret = "1"
+                EventMesh.publish("send_ble_scan","1")
+                # EventMesh.publish("send_ble_adv_switch","1")
+            elif data == "0":
+                s_ret = "0"
+                EventMesh.publish("send_ble_scan","0")
+            pass
+            
+        print("recv bt_scan{}".format(msg))
+        EventMesh.publish(WEB_CMD_ENUM.BT_SCAN_S_CMD,s_ret)
 
+#蓝牙当前状态
+class IOTWeb_get_bt_stateProtoCol(ProtoCol):
+    """get_bt_state"""
+    TYPE = "get_bt_state"
 
-class NetManager(Abstract):
-    THRESHOLD = 10
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        bt_state ={
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"get_bt_state",
+                "rest":msg,
+                "msg":"上报蓝牙开关状态"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(bt_state)
+        print("send_data bt_state{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-    def __init__(self):
-        self.__data_call = dataCall
-        self.__net = net
-        self.check_net = checkNet.CheckNetwork("QuecPython_Helios_Framework", "this latest version")
-        EventMesh.subscribe("get_network_state", self.get_network_state)
-        self.network_state = 0
+    def recv(self, event, msg):
+        """
 
-    def post_processor_after_instantiation(self, *args, **kwargs):
-        count = 0
-        while True:
-            count += 1
-            if count > 5 :
-                return
-            data = dataCall.getInfo(1, 0)
-            EventMesh.debug_log("data call INFO {}".format(data))
-            if data[2][0]:
-                self.network_state = 1
-                break
-            utime.sleep(1)
-        self.__data_call.start(2, 0, "", "", "", 0)
-        self.__data_call.setCallback(self.__datacall_cb)
+        @param event:上行下发bt_state
+        @param msg: 接收到的下行数据
+        """
+        print("recv bt_state{}".format(msg))
+        switch_bt_state = EventMesh.publish("get_storage_config","switch_bt_state")
+        if switch_bt_state == None:
+            switch_bt_state = 0
+        
+        EventMesh.publish(WEB_CMD_ENUM.BT_STATE_S_CMD,str(switch_bt_state))
 
-    def __datacall_cb(self, args):
-        pdp = args[0]
-        nw_sta = args[1]
-        if nw_sta == 1:
-            self.network_state = 1
-            EventMesh.debug_log("*** network %d connected! ***" % pdp)
+#蓝牙扫描列表
+class IOTWeb_bt_scan_restProtoCol(ProtoCol):
+    """bt_scan_rest"""
+    TYPE = "bt_scan_rest"
 
-        else:
-            self.network_state = 0
-            EventMesh.debug_log("*** network %d not connected! ***" % pdp)
-           
-    def get_network_state(self, topic, msg):
-        return self.network_state 
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
 
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        print(" bt_scan_rest{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-class ProtoCol(Abstract):
-    TYPE = ""
-    HEADER = "#@{}@#;"
-    SEPARATOR = ";"
-    END = ";" + chr(0x01)
-    #PID = "SZKW"
-    #PID = "qAELPTKmFanR4RHe"
-    md5_key = ''
-    PID = ''
+    def recv(self, event, msg):
+        """
 
-    def __init__(self):
-        self.content = None
-        self.check_sum = None
-        self.password = EventMesh.publish(constants.EVENT.GET_PASSWORD)
-        self.imei = EventMesh.publish(constants.EVENT.GET_IMEI)
-        self.cid = EventMesh.publish(constants.EVENT.GET_CID)
-        self.imsi = EventMesh.publish(constants.EVENT.GET_IMSI)
-        self.key = EventMesh.publish(constants.EVENT.GET_KEY)
-        self.HEADER = self.HEADER.format(self.TYPE)
-
-        self.md5_key = ''
-        self.PID = ''
-        server_data = EventMesh.publish("get_new_key_pid")#获取pid和key
-        if server_data == None:
-            server_data = server_init()#如果获取的数据是None,就用默认的大锤key和pid
-            self.md5_key = server_data[2]
-            self.PID = server_data[3]
-        else:
-            self.md5_key = server_data[0]
-            self.PID = server_data[1]
-        
-        # EventMesh.debug_log("md5_key:--",self.md5_key,self.PID)
-        # ip_infor = {}
-        # ip_infor = EventMesh.publish("get_new_ip_com")
-        # if ip_infor != None:
-        #     self.md5_key = ip_infor[2]
-        # EventMesh.debug_log("md5_key",self.md5_key)
-
-    def initialization(self, *args, **kwargs):
-        EventMesh.subscribe(self.TYPE + "_SEND", self.handler)
-        EventMesh.subscribe(self.TYPE + "_RECV", self.handler)
-        #EventMesh.debug_log("ProtoCol:{}".format(self.TYPE + "_SEND"))
+        @param event:上行下发bt_scan_rest
+        @param msg: 接收到的下行数据
+        """
+        print("recv bt_scan_rest{}".format(msg))
+        
 
-    def handler(self, event, msg):
-        #EventMesh.debug_log("ProtoCol:handler:{}".format(event))
-        self.password = EventMesh.publish(constants.EVENT.GET_PASSWORD)
-        self.imei = EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166" #EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI) #"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI) #"867387060319166"#"867387060319188"#"867387060319177"#"867387060319166"#"860132060004322"#"867387060319166"#"860132060004322"#EventMesh.publish(constants.EVENT.GET_IMEI)
-        self.cid = EventMesh.publish(constants.EVENT.GET_CID)
-        self.imsi = EventMesh.publish(constants.EVENT.GET_IMSI)
-        self.key = EventMesh.publish(constants.EVENT.GET_KEY)
-        if event.endswith("_SEND"):
-            self.send(event, msg)
-        else:
-            self.recv(event, msg)
+#连接目标蓝牙设备
+class IOTWeb_connect_btProtoCol(ProtoCol):
+    """connect_bt"""
+    TYPE = "connect_bt"
 
     def send(self, event, msg):
-        pass
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        connect_bt = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"connect_bt",
+                "rest":"success",
+                "msg":"收到蓝牙连接请求"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(connect_bt)
+        print("send_data bt_state{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
     def recv(self, event, msg):
-        pass
+        """
 
-    @staticmethod
-    def get_date():
-        return "{:04d}-{:02d}-{:02d}".format(*utime.localtime()[0:3])
+        @param event:上行下发connect_bt
+        @param msg: 接收到的下行数据
+        """
+        # {
+        #     "cmd":"connect_bt",
+        #     "ts":1738283829,
+        #     "msg":"连接蓝牙设备",
+        #     "data":"目标设备mac地址"
+        # }
+        if "data" in msg:
+            mac = msg["data"]
+            mac = "75:e8:8c:62:9a:df"
+            EventMesh.publish("send_connect_bt_mac",mac)
+        EventMesh.publish(WEB_CMD_ENUM.CONNECT_BT_S,None)
+        print("recv connect_bt{}".format(msg))
+#上报连接记录
+class IOTWeb_bt_connect_record_listProtoCol(ProtoCol):
+    """bt_connect_record_list"""
+    TYPE = "bt_connect_record_list"
 
-    @staticmethod
-    def get_time():
-        return "{:02d}:{:02d}:{:02d}".format(*utime.localtime()[3:6])
+    def send(self, event, msg):
+        print("send bt_connect_record_list{}".format(msg))
+        # 通过websocket发送到服务器端
+        # {
+        #     "cmd":"bt_connect_record_list",
+        #     "ts":1738283829,
+        #     "msg":"上报蓝牙连接列表",
+        #     "data":[
+        #         {
+        #             "name":"蓝牙名称",
+        #             "mac":"蓝牙地址",
+        #             "state":"connected/disconnected/connecting"
+        #         }
+        #     ]
+        # }
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        bt_connect_record_list = {
+            "cmd":"bt_connect_record_list",
+            "ts":time_tmp,
+            "msg":"上报蓝牙连接列表",
+            "data":[
+                {
+                    "name":"蓝牙名称",
+                    "mac":"12:34:56:78:78:87",
+                    "state":"connected"
+                },
+                 {
+                    "name":"蓝牙名称",
+                    "mac":"12:34:56:78:78:86",
+                    "state":"connecting"
+                },
+                {
+                    "name":"蓝牙名称",
+                    "mac":"12:34:56:78:78:85",
+                    "state":"connecting"
+                }
+            ]
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(bt_connect_record_list)
+        print("send_data bt_state{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
 
-    def calc_crc(self):
-        data = self.content
-        if not isinstance(data, bytes):
-            data = data.encode()
-        count = 0
-        for x in data:
-            count += x
-        self.check_sum = 100 - count % 100
+    def recv(self, event, msg):
+        """
 
-    def pack(self):
-        self.calc_crc()
-        return self.HEADER.encode() + self.content.encode() + self.SEPARATOR.encode() + int(self.check_sum).to_bytes(1,'little') + self.END.encode()
-    
-    def pack_MD5_head(self,data):                                                                                                                 
-        #key = "bZld0ALsZTt15tKEZhOlLPgbsO75BLTP"
-        self.md5_key=EventMesh.publish("get_new_key")
-        if self.md5_key == None:
-            self.md5_key = server_init[2]
-
-        if(self.md5_key == ""):
-            return ""
-        MD5_head = ""
-        hash_obj = uhashlib.md5(data+self.md5_key)
-        res = hash_obj.digest()
-
-        # 转成十六进制表示
-        MD5_head = ubinascii.hexlify(res)
-        MD5_head = MD5_head.decode('ascii')
-        #EventMesh.debug_log("data+self.md5_key:{}".format(data+self.md5_key))
-        #EventMesh.debug_log(res)
-        #EventMesh.debug_log(MD5_head)
-        return MD5_head
+        @param event:上行下发bt_connect_record_list
+        @param msg: 接收到的下行数据
+        """
+        # {
+        #     "cmd":"bt_connect_record_list",
+        #     "ts":1738283829,
+        #     "msg":"连接蓝牙设备",
+        #     "data":"目标设备mac地址"
+        # }
+        # {
+        #     "cmd":"post_rest",
+        #     "ts":1738283829,
+        #     "msg":"消息收到响应",
+        #     "data":{
+        #         "cmd":"bt_connect_record_list",
+        #         "rest":"success|error",
+        #         "msg":"收到蓝牙连接记录列表"
+        #     }
+        # }
+        print("recv bt_connect_record_list{}".format(msg))    
+#断开设备蓝牙连接
+class IOTWeb_disconnect_btProtoCol(ProtoCol):
+    """disconnect_bt"""
+    TYPE = "disconnect_bt"
+
+    def send(self, event, msg):
+        print("send schedule{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        disconnect_bt = {
+            "cmd":"post_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"disconnect_bt",
+                "rest":"success",
+                "msg":"断开蓝牙设备连接请求"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(disconnect_bt)
+        print("send_data bt_state{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:上行下发disconnect_bt
+        @param msg: 接收到的下行数据
+        """
+        #{
+        # 'msg': '断开设备蓝牙', 
+        # 'data': 'AB:12:34:56:78', 
+        # 'ts': 1754555005787, 
+        # 'cmd': 'disconnect_bt'}
+        if "data" in msg:
+            mac = msg["data"]
+            EventMesh.publish("send_disconnect_bt_mac",mac)
+        print("recv disconnect_bt{}".format(msg))
+        EventMesh.publish(DISCONNECT_BT_S,None)
 
 class LK_ProtoCol(ProtoCol):
     """链路保持"""
@@ -2125,7 +4007,7 @@ class CENTER_ProtoCol(ProtoCol):
         EventMesh.publish(constants.PROTOCOL.CENTER_SEND)  
 
 #呼叫快捷电话号码
-import voiceCall
+
 class MONITOR_ProtoCol(ProtoCol):
     """呼叫快捷号码"""
     TYPE = "MONITOR"
@@ -2247,8 +4129,6 @@ class sosHome_dial_ProtoCol(ProtoCol):
         EventMesh.publish("set_dial_sos_number",data)
              
         EventMesh.publish(constants.PROTOCOL.SOS_SEND)  
-
-  
 # 低电提醒
 #[XT*334588000000156*0008*LOWBAT,1]
 class LOWBAT_ProtoCol(ProtoCol):
@@ -3736,7 +5616,7 @@ class ProtoColResolver(object):
     def handler(self, data):
         # 这里接收数据
         
-        EventMesh.debug_log("handler -> {}".format(data))
+        EventMesh.debug_log("handler -> {}".format(len(data)))
         # if data.startswith('Init;'):
         #     data = data[5:]
         #     EventMesh.publish(constants.EVENT.SET_KEY, {"value": ujson.loads(data)['KEY']})
@@ -3746,14 +5626,8 @@ class ProtoColResolver(object):
         #     EventMesh.publish(constants.PROTOCOL.H04_RECV, data)
         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
+                playpolad_data(data)
+                # EventMesh.publish(ProtoCol_type, data) #返回协议read
         except Exception as e:
             EventMesh.debug_log("handler:ERROR:")
             usys.print_exception(e)
index 1ed017e..4bbbfc1 100644 (file)
@@ -252,7 +252,7 @@ class UI(object):
                 EventMesh.debug_log("__lcd_on:sleep_lock:error!")
             self.sleep_lock = 1
             self.sleep_flag = 0
-           
+            EventMesh.publish("sys_sleep_cb")#休眠前回调
             #lcd_ctrl.write(0)
             #
             #lv.autoSleep(1)
@@ -262,6 +262,7 @@ class UI(object):
            
             #utime.sleep_ms(80)
             #EventMesh.publish("set_lcd_state",self.sleep_flag)
+            
             self.sleep_lock = 0
            
             self.system_sleep_timer.stop()
diff --git a/2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/voice_record.py b/2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/voice_record.py
new file mode 100644 (file)
index 0000000..b5a6e7c
--- /dev/null
@@ -0,0 +1,242 @@
+from common import Abstract, LogAdapter
+import EventMesh
+import uwebsocket
+import usys
+import gc
+import urandom
+import uhashlib
+import ubinascii
+import ujson
+import osTimer
+import _thread
+from queue import Queue
+import utime
+import audio
+import uos
+from machine import Pin
+from machine import ExtInt
+from machine import WDT
+import modem
+import sim
+import net
+import base64
+import ucryptolib
+import urandom as random
+import request
+import ql_fs
+from misc import Power,USB,PowerKey
+import ntptime
+import machine
+import dataCall
+import constants
+import versions
+from machine import UART
+
+class VOICE_RECORD(Abstract): #静默录音
+    # VOICE_RECORD
+    
+    def __init__(self):
+        self.AI_record_tmp_queue = Queue(100)
+        self.AI_ASR_send_data_queue = Queue(200)
+        self.AI_VC_send_data_queue = Queue(100)
+        self.AI_audio_queue = Queue(100)
+        #self.AI_WS_connect_Queue = Queue(100) #释放用
+        self.AI_TTS_str = ""
+        self.AI_ASR_str = ""
+        self.AI_ASR_flag = 0
+        self.AI_ASR_str_tmp = ""
+        self.AI_ASR_send_buf_len = 0
+        self.AI_ASR_text_tmp = ""
+        self.AI_ASR_text_repet_count = 0
+            
+        self.VC_dialog_id = ""#
+        self.VC_message_id=None
+        self.VC_task_id =None
+        self.AI_client_VC = None
+        self.AI_client_VC_recv_id = 0
+        self.AI_client_VC_recv_lock = 0
+        self.AI_client_VC_isconnect =0
+        self.AI_client_VC_debug =0
+
+        self.key_state = 0
+
+        self.AI_client_asr = None
+        self.AI_client_asr_recv_id = 0
+        self.AI_client_asr_recv_lock = 0
+        self.AI_client_asr_isconnect =0
+        self.AI_ASR_timer =  osTimer()
+        self.AI_ASR_timer_count = 0
+        self.AI_client_asr_debug =0
+        self.AI_ASR_check_timeout = 0
+        self.AI_ASR_error_timeout = 0
+        self.VC_Thinking_timerout = 0
+
+        self.record_pcm = None
+        self.play_pcm = None
+        self.voice_record_thread_id = 0
+        self.VC_record_thread_lock = 0
+        self.VC_pingping_timerout = 0
+        self.asr_pingping_timerout = 0
+        self.factory_timer = osTimer()
+        self._1S_timer = osTimer()
+        self.Audio_buf_size = 16*1024
+        self.record = audio.Record()
+        #self.record.end_callback(self.record_callback)
+        self.record.gain_set(4,10)
+        #self.record.gain_set(4,12)
+        self.aud = audio.Audio(0)
+        #self.aud.setVolume(self.VC_TTS_volume //10)
+        self.audio_play_state = 1 #音频播放完状态
+        self.close_timerout = 0
+        self.LocalRespondingEnded_timerout = 0
+
+        self.VC_Play_flag = 0
+        self.play_flag = 0
+        self.VC_record_state_flag = 0
+        self.AI_key_long_press_flag = 0
+        self.websocket_error_count = 0
+
+        self.tts_in_data_len = 0
+        self.tts_out_data_len = 0
+        self.VC_satrt_flag = 0
+        self.session_id = ""
+        self.start_voice_record_flag = 0
+        self.connect_web_count = 0
+        self.iot_protocol_client = None
+        self.VC_record_samplerate = 16000
+        self.msgid_int = 0
+        self.AI_audio_queue_thread_id = 0
+        self.open_start = 0 #是否需要超时关闭静默录音
+        self.voice_timer_out = osTimer()
+      
+    def post_processor_after_instantiation(self):
+        EventMesh.subscribe("start_voice_record", self.start_voice_record)#开始静默录音
+        EventMesh.subscribe("stop_voice_record", self.stop_voice_record)#停止静默录音
+        EventMesh.subscribe("get_voice_record_flag", self.get_voice_record_flag)#停止静默录音
+    def get_voice_record_flag(self,event,msg):
+        return self.start_voice_record_flag
+    def start_voice_record(self,event,msg):
+        get_VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")
+        if get_VC_satrt_flag == None:
+            get_VC_satrt_flag = 0
+        if get_VC_satrt_flag == 1:
+            EventMesh.publish("stop_AI_record") #停止AI录音
+            self.start_voice_record_flag = 0
+        if self.start_voice_record_flag == 1:
+            return -1
+        #开启线程 
+        #开启录音
+        EventMesh.publish("stop_voice_record")
+        self.connect_web_count = 0
+        if self.voice_record_thread_id == 0:
+            _thread.stack_size((9+2)*1024)
+            self.voice_record_thread_id = _thread.start_new_thread(self.Voice_record_thread,())
+            _thread.stack_size(8*1024)
+
+        self.msgid_int = urandom.getrandbits(32)#随机生成32位的随机数
+        print(self.msgid_int)
+        self.start_voice_record_flag = 1
+        try:
+            self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0)
+        except Exception as e:
+            usys.print_exception(e)
+        if self.open_start == 1:
+            self.voice_timer_out.start(10*60*1000,0,self.timerOut)
+        # EventMesh.publish("open_websocket_timer")
+        print("start_voice_record")
+        return 1
+    def timerOut(self,*argc):
+        EventMesh.publish("stop_voice_record")
+        pass
+    
+    def stop_voice_record(self,event,msg):
+        if self.start_voice_record_flag == 1:
+            
+            try:
+                if self.voice_record_thread_id != 0:
+                    try:
+                        _thread.stop_thread(self.voice_record_thread_id)
+                    except Exception as e:
+                        usys.print_exception(e)
+            except Exception as e:
+                usys.print_exception(e)
+            self.voice_record_thread_id=0
+            self.aud.stopPlayStream()
+            self.aud.stopAll()
+            self.record.stream_stop()
+            self.record.stop()#关闭录音
+            Record_read_buf = bytearray(self.Audio_buf_size)
+            for i in range(10):
+                Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
+                print("Record_len:!!!!!!{}".format(Record_len))
+                if Record_len <= 0:
+                    break
+        self.start_voice_record_flag = 0
+        self.voice_record_thread_id = 0
+        self.AI_audio_queue_thread_id = 0
+        self.start_voice_record_flag
+        self.connect_web_count = 0
+        if self.open_start == 1:
+            self.voice_timer_out.stop()
+        print("stop_voice_record")
+
+    
+    # 音频队列        
+    def AI_audio_queue_thread(self):
+        print("AI_audio_queue_thread start")
+        while True:
+            if self.start_voice_record_flag == 0:
+                break
+            if self.AI_audio_queue.empty() == False:
+                data = self.AI_audio_queue.get()
+                if data != None:
+                    try:
+                        signal = net.csqQueryPoll()
+                        if signal == -1 or sim.getStatus() != 1:#网络正常
+                            EventMesh.publish("stop_voice_record")
+                            break
+                        if self.iot_protocol_client != None:
+                            self.iot_protocol_client.send(data)
+                        else:
+                            EventMesh.publish("stop_voice_record")
+                            EventMesh.publish("start_voice_record")
+
+                    except Exception as e:
+                        usys.print_exception(e)
+                        EventMesh.publish("stop_voice_record")
+                        EventMesh.publish("start_voice_record")
+                        break
+            pass
+        print("AI_audio_queue_thread exit")
+        self.AI_audio_queue_thread_id = 0
+       
+    
+    
+    #获取录音数据
+
+    def Voice_record_thread(self):
+        while True:
+            try:
+                if self.start_voice_record_flag == 0:
+                    break
+                # 死循环接收数据
+                Record_read_buf = bytearray(self.Audio_buf_size)
+                Record_len = 0
+                Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
+                if Record_len > 0:
+                    read_buf = bytes(Record_read_buf[:Record_len])
+                    try:
+                        #发送静默录音数据到iot平台
+                        EventMesh.publish("SEND_AUDIO_TO_IOT",[read_buf,self.msgid_int])
+                    except Exception as e:
+                        usys.print_exception(e)
+                    print("voice Record_len:{}".format(Record_len))
+                    
+                
+            except Exception as e:
+                usys.print_exception(e)
+            utime.sleep_ms(100)
+        print("Voice_record_thread:exit")
+        self.voice_record_thread_id = 0
+        
+