Browse Source

json版本,和分包

kinve 1 năm trước cách đây
mục cha
commit
b873fc5dc0
3 tập tin đã thay đổi với 441 bổ sung293 xóa
  1. 196 165
      ble.py
  2. 245 128
      config.json
  3. BIN
      dist/ble.exe

+ 196 - 165
ble.py

@@ -16,6 +16,7 @@ import threading
 import ctypes
 import inspect
 import re
+import base64
 
 from message_base import MessageBase
 from websocket_server import WebServer
@@ -60,6 +61,7 @@ g_config = {}
 g_ble_mtu = 20
 g_ble_client = None
 g_download_cfg = {"Key":"", "Total":0, "Number":0, "DataCrc16":0}
+g_recv_count = 0
 
 mb = None
 ws = None
@@ -271,11 +273,13 @@ def batch_split_key_value(input_str):
 def recv_handler(data: bytearray, reve=False):
     mq.add("ble_recv", data)
 
+# 记录数据
 def notification_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
     global mq
-    # recv_handler(data)
     mq.add("ble_recv", data)
-    mq.add("ws_send", data)
+    if ws:
+        mq.add("ws_send", data)        
+
 
 async def ble_send(client, data):
     global recv_start_time
@@ -290,13 +294,12 @@ async def ble_send(client, data):
     send_start_time = time.time()
     try: 
         while send_count<all_count:
-            cur_len = frame_len
-            if all_count-send_count<frame_len:
-                cur_len = all_count-send_count
-
+            cur_len = frame_len if all_count-send_count>=frame_len else all_count-send_count
             s = data[send_count:send_count+cur_len]
             await client.write_gatt_char(g_config["def_cfg"]["write_char"], s)
+            await asyncio.sleep(0.050)  
             send_count += cur_len
+            logger.info('发送包:{}/{}'.format(send_count, all_count)) 
     except Exception as e: 
         logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
             
@@ -304,7 +307,7 @@ async def ble_send(client, data):
     send_end_time = time.time()   
     recv_start_time = time.time()  
     logger.info('发送耗时:%.3fs', send_end_time - send_start_time)   
-    await asyncio.sleep(g_config["def_cfg"]["ble_send_wait"])           #每休眠1秒发送一次  
+    # await asyncio.sleep(g_config["def_cfg"]["ble_send_wait"])           #每休眠1秒发送一次  
          
 
 import sys, select
@@ -317,7 +320,8 @@ def print_data_list():
     global g_config
     try:
         for i in range(len(g_config["cmd_list"])):
-            print(i, g_config["cmd_list"][i][2])
+            # print(i, g_config["cmd_list"][i][2])
+            print(i, g_config["cmd_list"][i]["note"])
     except Exception as e: 
         logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
 
@@ -331,34 +335,34 @@ def send_form_data_list(client, i, data=None):
             return None  
         json_data = g_config["cmd_list"][i] 
 
-    if len(json_data) < 3: 
-        return
+    # if len(json_data) < 3: 
+    #     return
     
-    byte_sequence = b''
-    if len(json_data[0]) > 4:
-        if json_data[0][:4] == "hex:":
-            byte_sequence += bytes.fromhex(json_data[0][4:]) 
-        elif json_data[0][:4] == "str:":    
-            byte_sequence += bytes(json_data[0][4:], 'utf-8')
-        elif json_data[0][:4] == "bin:":     
-            byte_value = int(json_data[0][4:], 2)  # 将二进制字符串转换为整数
-            byte_array = bytes([byte_value])  # 将整数转换为单字节的字节串
-            byte_sequence += byte_array
-
-    if len(json_data[1]) > 4:
-        if json_data[1][:4] == "hex:":
-            byte_sequence += bytes.fromhex(json_data[1][4:]) 
-        elif json_data[1][:4] == "str:":    
-            byte_sequence += bytes(json_data[1][4:], 'utf-8')
-        elif json_data[1][:4] == "bin:":     
-            byte_value = int(json_data[1][4:], 2)  # 将二进制字符串转换为整数
-            byte_array = bytes([byte_value])  # 将整数转换为单字节的字节串
-            byte_sequence += byte_array
-
+    # byte_sequence = b''
+    # if len(json_data[0]) > 4:
+    #     if json_data[0][:4] == "hex:":
+    #         byte_sequence += bytes.fromhex(json_data[0][4:]) 
+    #     elif json_data[0][:4] == "str:":    
+    #         byte_sequence += bytes(json_data[0][4:], 'utf-8')
+    #     elif json_data[0][:4] == "bin:":     
+    #         byte_value = int(json_data[0][4:], 2)  # 将二进制字符串转换为整数
+    #         byte_array = bytes([byte_value])  # 将整数转换为单字节的字节串
+    #         byte_sequence += byte_array
+
+    # if len(json_data[1]) > 4:
+    #     if json_data[1][:4] == "hex:":
+    #         byte_sequence += bytes.fromhex(json_data[1][4:]) 
+    #     elif json_data[1][:4] == "str:":    
+    #         byte_sequence += bytes(json_data[1][4:], 'utf-8')
+    #     elif json_data[1][:4] == "bin:":     
+    #         byte_value = int(json_data[1][4:], 2)  # 将二进制字符串转换为整数
+    #         byte_array = bytes([byte_value])  # 将整数转换为单字节的字节串
+    #         byte_sequence += byte_array
+    byte_sequence = json_data
     logger.info("发送前:{}".format(byte_sequence))
-    # data_str = json.dumps(json_data)
+    data_str = json.dumps(json_data)
     # 字符串编码为字节序列
-    # byte_sequence = str.encode(data_str)
+    byte_sequence = str.encode(data_str)
     # 字节序列转换为bytearray类型
     byte_array = bytearray(byte_sequence)
     byte_array = ev_packing(byte_array)
@@ -406,7 +410,7 @@ def input_call(client):
     userinput = None
     if g_download_cfg["Number"] == 0: #非批量获取配置的状态下
         try:  
-            userinput = inputimeout(prompt='请命令序号:', timeout=60)
+            userinput = inputimeout(prompt='请命令序号:', timeout=g_config["def_cfg"]["input_interval"])
         except TimeoutOccurred:
             userinput = None
     if userinput:
@@ -421,29 +425,6 @@ def input_call(client):
                 logger.info("json内容如下:")
                 print_data_list()    
           
-
-@calculate_time
-def auto_getcfg_call(client):
-    global g_config
-    global g_download_cfg
-    # 自动发送任务
-    try: 
-        if g_download_cfg["Number"]>0: 
-            new_one = []   
-            for i, v in enumerate(g_config["cmd_list"]):
-                if v[2] == "GetConfigurationNumber":
-                    new_one = copy.deepcopy(v)  #深拷贝 
-                    break   
-            if new_one:
-                Number = g_download_cfg["Number"] 
-                Total = g_download_cfg["Total"] 
-                new_one[3]["Number"] =  Number
-                send_form_data_list(client, 0, new_one)
-                g_download_cfg["Number"] = Number+1 if Number < Total else 0
-
-    except Exception as e: 
-        logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
-
 async def ble_main():
     global g_run
     global g_ble_client
@@ -476,18 +457,25 @@ async def ble_main():
         logger.info("尝试连接设备({})...".format(g_config["def_cfg"]["ble_mac"]))
 
         async with BleakClient(device,disconnected_callback=disconnected_callback) as client:
-            g_ble_client = client
-            logger.info("已连接(mtu=%d)", client.mtu_size)
-            g_ble_mtu = client.mtu_size-3
-            try: 
+            try:
+                g_ble_client = client
+                logger.info("已连接(mtu=%d)", client.mtu_size)
+                g_ble_mtu = client.mtu_size-3
+
+                # 是否连接
+                # if not client.is_connected:
+                #     client.connect()
+                # logger.info(f"连接状态: {client.is_connected}")
+                # 是否配对
+                # paired = await client.pair(protection_level=2)
+                # logger.info(f"配对: {paired}")
+                # 开启通知的接收
                 await client.start_notify(g_config["def_cfg"]["notif_char"], notification_handler)
-            except Exception as e: 
-                logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
+                # 循环发送指令
 
-            g_download_cfg["Number"] = 0
-
-            while client and client.is_connected and g_run:
-                try:
+                g_download_cfg["Number"] = 0
+                
+                while client.is_connected and g_run:
                     ble_data = mq.get("ble_send")
                     if ble_data:
                         await ble_send(client, ble_data)     
@@ -495,9 +483,20 @@ async def ble_main():
                     # 开始根据设备即功能处理消息
                     ws_data = mq.get("ws_recv")
                     if ws_data:
-                        await ble_send(client, ws_data)        
-                except Exception as e:
-                    logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
+                        await ble_send(client, ws_data)   
+                logger.info('断开连接')
+            except Exception as e:
+                logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
+            finally:
+                # try:
+                #     if client.is_connected: 
+                #         # 结束监听
+                #         await client.stop_notify(g_config["def_cfg"]["notif_char"])
+                #         # 断开与蓝牙设备的连接
+                #         await client.disconnect()
+                # except Exception as e:
+                #     logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
+                logger.info("结束")
 
     logger.info("结束:{}".format(inspect.currentframe().f_code.co_name)) 
 
@@ -538,100 +537,128 @@ def asyncio_handler():
     loop.run_until_complete(asyncio.wait([ble_main()]))
 
 
-def ble_recv_handler():
-    global g_run
+def ble_handler(dec_str):
+    try:
+        out = json.loads(str(dec_str))
+        if "key" in out and "value" in out and out["key"] == "fwreq":
+            file = str(out["value"]["file"])
+            addr = int(out["value"]["addr"])
+            size = int(out["value"]["size"]) 
+            filesize = os.stat(file).st_size
+            with open(file, "rb") as f:
+                f.seek(addr)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
+                datas = f.read(size)
+                f.close()
+
+                # 发送
+                fwdata = {
+                    "type": "set",
+                    "data": [
+                        {   
+                            "key":"fwdata", 
+                            "value":{"cur":addr, "total":filesize, "data": base64.b64encode(datas).decode("utf-8")}
+                        }
+                    ],
+                    "note":"set_fwdata"
+                }	
+
+                byte_array = json.dumps(fwdata).encode("utf-8")
+                byte_array = ev_packing(byte_array)
+                send_data = bytes(byte_array)
+                mq.add("ble_send", send_data)
+                logger.info("add event:fwdata" )
+                
+    except Exception as e:
+        logger.error("Err in {}[{}]:\n {}".format(os.path.basename(e.__traceback__.tb_frame.f_globals["__file__"]), e.__traceback__.tb_lineno, e))
+
+def ble_unpack(data):
     global recv_start_time
     global g_download_cfg
-    while g_run:
-        data = mq.get("ble_recv")
-        if not data:
-            time.sleep(0.01)  
-            continue
+    global g_recv_count
+    global recv_data
+    HEAD_SEND = str(g_config["def_cfg"]["head_send"])
+    HEAD_RECV = str(g_config["def_cfg"]["head_recv"])
 
-        if g_config["def_cfg"]["recv_detail_print"]:
-            logger.info("包接收:{}".format(bytes(data))) 
+    # 如果当前包头是'EV>',直接清除之前的数据
+    if str(bytes(data)).startswith(HEAD_RECV):
+        recv_data.clear()
 
-        for d in data:   
-            recv_data.append(d)
+    for d in data:   
+        recv_data.append(d)
 
-        if len(recv_data)>1500:
-            recv_data.clear()
-            return        
+    if g_config["def_cfg"]["recv_detail_print"]:
+        logger.info("包接收({}),总长度({}):{}".format(len(data), len(recv_data),bytes(data)))   
 
-        if len(recv_data)<PACK_LEN():
-            return
+    if len(recv_data)>g_config["def_cfg"]["ble_pack_size"]:
+        recv_data.clear()
+        return        
 
-        recv_data_str = str(bytes(recv_data))
-        HEAD_SEND = str(g_config["def_cfg"]["head_send"])
-        HEAD_RECV = str(g_config["def_cfg"]["head_recv"])
-        reve=True
-        find_head = HEAD_SEND if not reve else HEAD_RECV
-        index = -1
-        if find_head != "":
-            index = recv_data_str.find(find_head)#'EV>'
-            if index < 2:
-                return
-        index -= 2
-        data_len = (recv_data[index+4]&0xff) | (recv_data[index+3]&0xff)<<8
-        if index+PACK_LEN()+data_len > len(recv_data):
+    if len(recv_data)<PACK_LEN():
+        return
+    
+    g_recv_count = g_config["def_cfg"]["heart_beat_interval"] 
+
+    recv_data_str = str(bytes(recv_data))
+    find_head =  HEAD_RECV
+    index = -1
+    if find_head != "":
+        index = recv_data_str.find(find_head)#'EV>'
+        if index < 2:
+            return
+    index -= 2
+    data_len = (recv_data[index+4]&0xff) | (recv_data[index+3]&0xff)<<8
+    if len(recv_data) < data_len+index+PACK_LEN():
+        logger.info("数据不够%d < %d(index(%d),head(%d),len(%d):0x%02x%02x)", len(recv_data), index+PACK_LEN()+data_len, index,PACK_LEN(),data_len, recv_data[index+3], recv_data[index+4])
+        return
+    
+    if g_config["def_cfg"]["recv_soc_data_print"]:
+        logger.info("接收:{}".format(bytes(recv_data).hex())) 
+
+    if recv_start_time:
+        recv_end_time = time.time()   
+        logger.info('接收耗时:%.3fs', recv_end_time - recv_start_time)  
+        recv_start_time = 0     
+
+    soc_data = recv_data[index+PACK_LEN():index+PACK_LEN()+data_len]
+    if g_config["def_cfg"]["checknum_type"]!="":
+        H = len(g_config["def_cfg"]["head_send"])
+        L = 2
+        get_crc = (recv_data[index+(H+L+1)]&0xff)| (recv_data[index+(H+L)]&0xff)<<8 
+        check_num = checknum_16(soc_data)
+        if get_crc != check_num:
+            logger.info("校验失败(%d):0x%04X 0x%04X", len(recv_data), get_crc, check_num)
+            recv_data.clear()
             return
-        
-        if g_config["def_cfg"]["recv_soc_data_print"]:
-            logger.info("接收:{}".format(bytes(recv_data).hex())) 
-
-        if recv_start_time:
-            recv_end_time = time.time()   
-            logger.info('接收耗时:%.3fs', recv_end_time - recv_start_time)  
-            recv_start_time = 0     
-
-        soc_data = recv_data[index+PACK_LEN():index+PACK_LEN()+data_len]
-        if g_config["def_cfg"]["checknum_type"]!="":
-            H = len(g_config["def_cfg"]["head_send"])
-            L = 2
-            get_crc = (recv_data[index+(H+L+1)]&0xff)| (recv_data[index+(H+L)]&0xff)<<8 
-            check_num = checknum_16(soc_data)
-            if get_crc != check_num:
-                logger.info("校验失败(%d):0x%04X 0x%04X", len(recv_data), get_crc, check_num)
-                return
-
-        logger.info("校验成功")
-
-        if g_config["def_cfg"]["aes_cbc_enbable"]:
-            find_type= "recv" if not reve else 'send'
-            key = get_aes_key(find_type) #"recv"
-            dec_data = AES_Decrypt(bytes(key), bytes(key), bytes(soc_data))
-            logger.info("解密后:{}".format(bytes(dec_data))) 
-        else:
-            dec_data = soc_data
 
-        dec_str = bytes(dec_data).decode('utf-8')
-        logger.info("解析:{}".format(dec_str) )
-        
-        # 特殊处理:升级
-        out = batch_split_key_value(dec_str)
-        if "fwreq" in out.keys():
-            values = out["fwreq"]
-            if len(values) == 3:
-                file = str(values[0])
-                addr = int(values[1])
-                size = int(values[2]) 
-                filesize = os.stat(file).st_size
-                with open(file, "rb") as f:
-                    f.seek(addr)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
-                    datas = f.read(size)
-                    f.close()
-
-                    # 发送
-                    byte_array = bytearray("set:fwdata={}/{},".format(addr, filesize), encoding="utf8")+bytearray(datas)
-                    byte_array = ev_packing(byte_array)
-                    send_data = bytes(byte_array)
-                    mq.add("ble_send", send_data)
-                    logger.info("add event:fwdata" )
-
-        # 清理
-        recv_data.clear()
+    logger.info("校验成功")
 
+    if g_config["def_cfg"]["aes_cbc_enbable"]:
+        key = get_aes_key("recv") #"recv"  'send'
+        dec_data = AES_Decrypt(bytes(key), bytes(key), bytes(soc_data))
+        logger.info("解密后:{}".format(bytes(dec_data))) 
+    else:
+        dec_data = soc_data
 
+    dec_str = bytes(dec_data).decode('gbk')
+    logger.info("解析:{}".format(dec_str) )
+    
+    # 特殊处理:升级
+    # out = batch_split_key_value(dec_str)
+    ble_handler(dec_str)
+
+    # 清理
+    recv_data.clear()
+
+def ble_recv_handler():
+    global g_run
+
+    while g_run:
+        data = mq.get("ble_recv")
+        if data:        
+            ble_unpack(data)
+
+        time.sleep(0.1)  
+        
     logger.info("结束:{}".format(inspect.currentframe().f_code.co_name))     
 
 def key_handler():
@@ -649,21 +676,26 @@ def key_handler():
 
 def main_handler():
     global g_run
+    global g_recv_count
     read_config_time = 0
-    heart_beart_time = 0
+    sec_count = 0
 
     while g_run:
-        if time.time()-read_config_time >= 3:
+        if time.time()-sec_count >= 1:
+            sec_count = time.time()
+            if g_recv_count > 0:
+                g_recv_count -= 1
+
+        if time.time()-read_config_time >= 5:
             read_config_time = time.time()
             read_config_call()
 
-        if g_config["def_cfg"]["auto_send_GetConfigurationNumber"] and g_download_cfg["Number"]>0:  
-            auto_getcfg_call(None)   
-
-        elif g_config["def_cfg"]["heart_beat_interval"] >0 and time.time()-heart_beart_time>=g_config["def_cfg"]["heart_beat_interval"]:
-            heart_beart_time = time.time()
-            heart_beat_call(None)
+        if g_ble_client and g_ble_client.is_connected:
+            if g_recv_count == 0:
+                g_recv_count = g_config["def_cfg"]["heart_beat_interval"] 
+                heart_beat_call(None)
 
+        time.sleep(0.1)   
  
 
     logger.info("结束:{}".format(inspect.currentframe().f_code.co_name)) 
@@ -686,7 +718,6 @@ if __name__ == "__main__":
     # test_recv()
     import websockets
     mq = MessageBase()
-    ws = WebServer("0.0.0.0", 11100, mq)
 
     thread_list.append(threading.Thread(target=main_handler, args=()))
     thread_list.append(threading.Thread(target=key_handler, args=()))
@@ -694,9 +725,9 @@ if __name__ == "__main__":
     for thread in thread_list:
         thread.start()
 
-
-    ws_serve = websockets.serve(ws.echo, ws.host, ws.port)
-    asyncio.get_event_loop().run_until_complete(ws_serve)
+    # ws = WebServer("0.0.0.0", 11100, mq)
+    # ws_serve = websockets.serve(ws.echo, ws.host, ws.port)
+    # asyncio.get_event_loop().run_until_complete(ws_serve)
     task = asyncio.get_event_loop().create_task(ble_main())
     asyncio.get_event_loop().run_until_complete(task)
 

+ 245 - 128
config.json

@@ -6,12 +6,13 @@
 		"ble_mac2": "E9:8B:FC:41:3F:CF",
 		"ble_mac3": "DB:57:46:A6:14:22",
 		"heart_beat_sel": 1,
-		"input_interval": 5,
-		"heart_beat_interval": 25,	
+		"input_interval": 3,
+		"heart_beat_interval": 15,	
 		"notif_char": "49535343-8841-43f4-a8d4-ecbe34729bb3",
 		"write_char": "49535343-1e4d-4bd9-ba61-23c647249616",
 		"ble_mtu": 0,
-		"ble_send_wait": 1.5,
+		"ble_send_wait": 3,
+		"ble_pack_size": 2048,
 		"head_send3": "",
 		"head_recv3": "",
 		"checknum_type3": "",
@@ -22,144 +23,260 @@
 		"aes_cbc_enbable": false,
 		"aes_cbc_key_send": "",
 		"aes_cbc_key_recv": "",	
-		"recv_detail_print": false,			
+		"recv_detail_print": true,			
 		"recv_soc_data_print": true,
-		"recv_analysis_data_print": false, 		
-		"auto_send_GetConfigurationNumber": true
+		"recv_analysis_data_print": false 		
 	},
 	
 	"cmd_list":	
 	[
-		[
-			"",
-			"str:get:version=?",
-			"get_soft_version"
-		],
-		[
-			"",
-			"str:get:heart_beat=?",
-			"heart_beat_sel"
-		],
-		[
-			"",
-			"get:time=?",
-			"get_time"
-		],	
-		[
-			"",
-			"str:get:work_status=?",
-			"get_work_status"
-		],
-		[
-			"",
-			"str:get:fire_status=?",
-			"get_fire_status"
-		],	
-		[
-			"",
-			"str:get:fault_status=?",
-			"get_fault_status"
-		],
-		[
-			"",
-			"str:get:humidity=?",
-			"get_humidity"
-		],
-		[
-			"",
-			"str:get:temperature=?",
-			"get_temperature"
-		],
-		[
-			"",
-			"str:get:cur_photosen0=?",
-			"get_cur_photosen"
-		],	
-		[
-			"",
-			"str:get:photosen0=?",
-			"get_photosen"
-		],
-		[
-			"",
-			"str:get:net=?",
-			"get_net"
-		],
+		{
+			"type": "get",
+			"data": [
+				{"key":"version", "value":"?"}
+			],
+			"note":"get_soft_version"
+		},
+		{
+			"type": "get",
+			"data": [
+				{"key":"heart_beat", "value":"?"}
+			],
+			"note":"heart_beat_sel"
+		},
+
+
+		{
+			"type": "get",
+			"data": [
+				{"key":"heart_beat", "value":"?"},
+				{"key":"time", "value":"?"},
+				{"key":"version", "value":"?"},
+				{"key":"hw_version", "value":"?"},
+				{"key":"work_status", "value":"?"},
+				{"key":"fire_status", "value":"?"},
+				{"key":"fault_status", "value":"?"}
+			],
+			"note":"get_info"
+		},
+
+		{
+			"type": "get",
+			"data": [
+				{"key":"serial_number", "value":"?"},
+				{"key":"photo_address", "value":"?"},
+				{"key":"install_address", "value":"?"},
+				{"key":"baud_rate", "value":"?"}
+			],
+			"note":"get_info2"
+		},
 		
-		[
-			"",
-			"str:get:event_num=?",
-			"get_event_num"
-		],
+
+		{
+			"type": "get",
+			"data": [
+				{"key":"net", "value":"?"},
+				{"key":"event_num", "value":"?"},
+				{"key":"warning_num", "value":"?"}
+			],
+			"note":"get_cfg"
+		},
+
+		{
+			"type": "get",
+			"data": [
+				{"key":"scene_tm", "value":{"channel":0}},
+				{"key":"scene_photosen", "value":{"channel":0}}
+			],
+			"note":"get_scene"
+		},
 	
-		[
-			"",
-			"str:get:warning_num=?",
-			"get_warning_num"
-		],
+		{
+			"type": "get",
+			"data": [
+				{"key":"humidity", "value":"?"},
+				{"key":"temperature", "value":"?"},
+				{"key":"cur_pressure", "value":{"channel":0}},
+				{"key":"cur_photosen", "value":{"channel":0}},
+				{"key":"cur_voltage", "value":"?"}
+			],
+			"note":"get_sensor"
+		},		
+
 		
-		[
-			"",
-			"str:set:extra_time=180",
-			"set_extra_time"
-		],	
-		[
-			"",
-			"str:set:standing_time=10",
-			"set_standing_time"
-		],	
-		[
-			"",
-			"str:set:interval_time=600",
-			"set_interval_time"
-		],	
-		[
-			"",
-			"str:set:photosen0=6000,6000,6000,6000",
-			"set_photosen"
-		],	
-		[
-			"",
-			"str:set:time=24,9,21,13,03,0",
-			"set_time"
-		],
-		[
-			"",
-			"str:set:reset=1",
-			"set_rest"
-		],
+		{
+			"type": "get",
+			"data": [
+				{"key":"sw_scene", "value":"?"},
+				{"key":"sw_pressure", "value":"?"},
+				{"key":"sw_enable", "value":{"channel":0}},
+				{"key":"sw_sec", "value":{"channel":0}},
+				{"key":"sw_warn", "value":{"channel":0}}
+			],
+			"note":"get_switch"
+		},	
+
+		{
+			"type": "get",
+			"data": [
+				{"key":"warning_page", "value":""}
+			],
+			"note":"get_warning_page"
+		},
+		{
+			"type": "get",
+			"data": [
+				{"key":"warning_data", "value":0}
+			],
+			"note":"get_warning_data"
+		},	
 	
-		[
-			"",
-			"str:set:net=WIFI24,12345678,qq.com,1883,user,123456",
-			"set_net"
-		],
-	
-		[
-			"",
-			"str:set:event_num=1000",
-			"set_event_num"
-		],
+		{
+			"type": "get",
+			"data": [
+				{"key":"event_page", "value":""}
+			],
+			"note":"get_event_page"
+		},
+		{
+			"type": "get",
+			"data": [
+				{"key":"event_data", "value":0}
+			],
+			"note":"get_event_data"
+		},	
+
+
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"extra_time", "value":180},
+				{"key":"standing_time", "value":10},
+				{"key":"interval_time", "value":600}
+			],
+			"note":"set_extra_time"
+		},	
+
+		
+		{
+			"type": "set",
+			"data": [
+				{
+					"key":"scene_tm", 
+					"value":{"channel":0, "val":[0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0]}
+				},
+				{
+					"key":"scene_photosen", 
+					"value":{"channel":0, "val":[9000,8000,7000,6000,5000,9500,8500,7500,6500,5500]}
+				},				
+				{
+					"key":"pressure", 
+					"value":{"channel":0, "val":50}
+				}			
+			],
+			"note":"set_scene"
+		},			
+		
+		{
+			"type": "set",
+			"data": [
+				{"key":"sw_scene", "value":1},
+				{"key":"sw_pressure", "value":1},
+				{"key":"sw_enable", "value":{"channel":0, "val":1}},
+				{"key":"sw_sec", "value":{"channel":0, "val":[1,1]}},
+				{"key":"sw_warn", "value":{"channel":0, "val":[1,1]}}
+			],
+			"note":"set_switch"
+		},	
 	
-		[
-			"",
-			"str:set:warning_num=1000",
-			"set_warning_num"
-		],
+		{
+			"type": "set",
+			"data": [
+				{"key":"net", "value":{
+					"wifi_ssid":"WIFI24",
+					"wifi_pass":"12345678",
+					"mqtt_host":"qq.com",
+					"mqtt_port":1883,
+					"mqtt_user":"user",
+					"mqtt_pass":"123456"}},
+				{"key":"event_num", "value":1000},
+				{"key":"warning_num", "value":1000}
+			],
+			"note":"set_cfg"
+		},	
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"photo_address", "value":"12345678"},
+				{"key":"install_address", "value":"深圳市龙岗区1"},
+				{"key":"baud_rate", "value":115200}
+			],
+			"note":"set_info"
+		},		
+
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"time", "value":1727107200}
+			],
+			"note":"set_time"
+		},	
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"mute", "value":1}
+			],
+			"note":"set_mute"
+		},	
 	
-		[
-			"",
-			"str:set:erase_bit=7",
-			"set_erase_bit"
-		],
+		{
+			"type": "set",
+			"data": [
+				{"key":"reset", "value":1}
+			],
+			"note":"set_reset"
+		},	
+		
 	
-		[
-			"",
-			"str:set:fwinfo=fire_detector17.bin.sum32",
-			"set_fwinfo"
-		]
+		{
+			"type": "set",
+			"data": [
+				{"key":"erase_bit", "value":7}
+			],
+			"note":"set_erase_bit"
+		},	
+		
+		{
+			"type": "set",
+			"data": [
+				{"key":"factory_reset", "value":1}
+			],
+			"note":"set_factory_reset"
+		},	
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"relay_trigger", "value":1}
+			],
+			"note":"set_relay_trigger"
+		},	
+
+
+		{
+			"type": "set",
+			"data": [
+				{"key":"fwinfo", "value":"fire_detector19.bin.sum32"}
+			],
+			"note":"set_fwinfo"
+		}	
 	
+
 	
 	]
 	}
-	
+	 

BIN
dist/ble.exe