chao 3 weeks ago
parent
commit
a89f794234

+ 22 - 74
blockly/blocks/python/ai.js

@@ -3581,7 +3581,7 @@ Blockly.Blocks['ai_vision_find_qrcode'] = {
         this.appendDummyInput()
             .appendField(new Blockly.FieldImage("blockly/media/ai_vision_qrcode_.png", 45, 45, { alt: "*", flipRtl: "FALSE" }));
         this.appendDummyInput()
-            .appendField("开始识别二维码")
+            .appendField(Blockly.Msg.image_process_text_recognize_qrcode)
         // .appendField(new Blockly.FieldVariable("canvas"), "varitem")
         // .appendField();
         this.setOutput(false, null);
@@ -3595,6 +3595,7 @@ Blockly.Blocks['ai_vision_find_qrcode'] = {
 
 Blockly.Python['ai_vision_find_qrcode'] = function (block) {
     // TODO: Assemble Python into code variable.
+    Blockly.Python.addVariable('findQrcode', "findQrcode = []", true);
     var code = 'findQrcode = canvas.find_qrcodes() \n';
     // TODO: Change ORDER_NONE to the correct strength.
     return code;
@@ -3603,11 +3604,7 @@ Blockly.Python['ai_vision_find_qrcode'] = function (block) {
 Blockly.Blocks['ai_vision_find_qrcode_result'] = {
     init: function () {
         this.appendDummyInput()
-            .appendField("屏幕显示二维码").
-            appendField(new Blockly.FieldDropdown([
-                ["源文本", "SourceText"],
-                ["检测框", "CheckBox"],
-            ]), "qrcode_result")
+            .appendField(Blockly.Msg.image_process_draw_qrcode_show)
         // .appendField(new Blockly.FieldVariable("canvas"), "varitem")
         // .appendField();
         this.setOutput(false, null);
@@ -3620,26 +3617,10 @@ Blockly.Blocks['ai_vision_find_qrcode_result'] = {
 };
 
 Blockly.Python['ai_vision_find_qrcode_result'] = function (block) {
-    let qrcode_result = block.getFieldValue('qrcode_result');
-    let qrcodeResultAllBlock = getBlocksByTypeName("ai_vision_find_qrcode_result")
-    // console.log("qrcode_result",qrcodeResultAllBlock[0].innerText)
-    let findQrcodeStr = qrcodeResultAllBlock[0].innerText
-    let Source = findQrcodeStr.indexOf("Source") != -1 ? "True" : "False"
-    let CheckBox = findQrcodeStr.indexOf("CheckBox") != -1 ? "True" : "False"
-    Blockly.Python.addFunction("showQRcodeResult", `def showQRcodeResult(Source,CheckBox):
-    global findQrcode
-    for i in findQrcode:
-        if Source:
-            canvas.draw_string((i["x"]),(i["y"]), (i["payload"]), scale = 1, color = (255,0,0) , thickness = 1)
-        if CheckBox:
-            canvas.draw_rectangle((i["x"]),(i["y"]), (i["x"])+(i["w"]),(i["y"])+ (i["h"]), color=(255,0,0), thickness=1)
-`)
-    // TODO: Assemble Python into code variable.
-    let code = ""
-    if (qrcodeResultAllBlock[0].id == block.id) {
-        code = `showQRcodeResult(${Source},${CheckBox})
+    let code = `for i in findQrcode:
+    canvas.draw_string((i["x"]),(i["y"]), (i["payload"]), scale = 1, color = (255,0,0) , thickness = 1)
+    canvas.draw_rectangle((i["x"]),(i["y"]), (i["x"])+(i["w"]),(i["y"])+ (i["h"]), color=(255,0,0), thickness=1)
 `
-    }
     // TODO: Change ORDER_NONE to the correct strength.
     return code;
 };
@@ -3700,11 +3681,6 @@ Blockly.Blocks['ai_vision_apriltag_get_info'] = {
     init: function () {
         this.appendDummyInput()
             .appendField(Blockly.Msg.ai_vision_apriltag_get_result)
-            .appendField(new Blockly.FieldDropdown([
-                [Blockly.Msg.ai_vision_pattern_detection_content, "ApriltagId"],
-                // [Blockly.Msg.ai_vision_pattern_detection_type_id, "id"],
-                [Blockly.Msg.ai_vision_pattern_detection_type_family, "ApriltagCheckout"]
-            ]), "get_info");
         this.setInputsInline(false);
         // this.setOutput(true, null);
         this.setNextStatement(true, null);
@@ -3729,22 +3705,11 @@ Blockly.Blocks['ai_vision_apriltag_get_info'] = {
 };
 
 Blockly.Python['ai_vision_apriltag_get_info'] = function (block) {
-    var variable_name = Blockly.Python.variableDB_.getName(block.getFieldValue('varitem'), Blockly.Variables.NAME_TYPE);
-    var dropdown_name = block.getFieldValue('get_info');
-    let apriltagAllBlock = getBlocksByTypeName("ai_vision_apriltag_get_info")
-    let findQrcodeStr = apriltagAllBlock[0].innerText
-    let ApriltagId = findQrcodeStr.indexOf("ApriltagId") != -1 ? "True" : "False"
-    let ApriltagCheckout = findQrcodeStr.indexOf("ApriltagCheckout") != -1 ? "True" : "False"
-    Blockly.Python.addFunction("getApriltagCanvasResult", `def getApriltagCanvasResult(ApriltagId,ApriltagCheckout):
-    global findApriltags
-    for i in findApriltags:
-        if apriltagId:
-            canvas.draw_string((i["x"]),(i["y"]), (i["id"]), scale = 1, color = (255,0,0) , thickness = 1)
-        if ApriltagCheckout:
-            canvas.draw_rectangle((i["x"]),(i["y"]), (i["x"])+(i["w"]),(i["y"])+ (i["h"]), color=(255,0,0), thickness=1)
-    )`)
     // TODO: Assemble Python into code variable.
-    var code = `getApriltagCanvasResult(${ApriltagId},${ApriltagCheckout})`;
+    var code = `for i in findApriltags:
+    canvas.draw_string((i["x"]),(i["y"]), (i["id"]), scale = 1, color = (255,0,0) , thickness = 1)
+    canvas.draw_rectangle((i["x"]),(i["y"]), (i["x"])+(i["w"]),(i["y"])+ (i["h"]), color=(255,0,0), thickness=1)
+    `;
     // TODO: Change ORDER_NONE to the correct strength.
     return code;
 };
@@ -3832,7 +3797,7 @@ Blockly.Blocks['ai_vision_find_barcodes'] = {
         this.appendDummyInput()
             .appendField(new Blockly.FieldImage("blockly/media/ai_vision_barcode_.png", 45, 45, { alt: "*", flipRtl: "FALSE" }));
         this.appendDummyInput()
-            .appendField(Blockly.Msg.ai_vision_get_canvas + Blockly.Msg.ai_vision_barcode_detected_result)
+            .appendField(Blockly.Msg.ai_vision_barcode_detected_result)
         // .appendField(new Blockly.FieldVariable("canvas"), "varitem")
         // .appendField();
         this.setNextStatement(true);
@@ -3846,6 +3811,7 @@ Blockly.Blocks['ai_vision_find_barcodes'] = {
 Blockly.Python['ai_vision_find_barcodes'] = function (block) {
     // var variable_name = Blockly.Python.variableDB_.getName(block.getFieldValue('varitem'), Blockly.Variables.NAME_TYPE);
     // TODO: Assemble Python into code variable.
+    Blockly.Python.addVariable('findBarcodes', "findBarcodes = []", true);
     var code = 'findBarcodes = canvas.find_barcodes() \n';
     // TODO: Change ORDER_NONE to the correct strength.
     return code;
@@ -3856,10 +3822,6 @@ Blockly.Blocks['ai_vision_barcodes_get_info'] = {
     init: function () {
         this.appendDummyInput()
             .appendField("屏幕显示条形码")
-            .appendField(new Blockly.FieldDropdown([
-                [Blockly.Msg.ai_vision_pattern_detection_content, "barcodesPayload"],
-                [Blockly.Msg.ai_models_face_model_rect, "barcodesCorners"]
-            ]), "get_info");
         this.setInputsInline(false);
         this.setOutput(false, null);
         this.setNextStatement(true);
@@ -3884,32 +3846,18 @@ Blockly.Blocks['ai_vision_barcodes_get_info'] = {
 
 Blockly.Python['ai_vision_barcodes_get_info'] = function (block) {
     var dropdown_name = block.getFieldValue('get_info');
-    let qrcodeResultAllBlock = getBlocksByTypeName("ai_vision_barcodes_get_info")
-    // console.log("qrcode_result",qrcodeResultAllBlock[0].innerText)
-    let findQrcodeStr = qrcodeResultAllBlock[0].innerText
-    let barcodesPayload = findQrcodeStr.indexOf("barcodesPayload") != -1 ? "True" : "False"
-    let barcodesCorners = findQrcodeStr.indexOf("barcodesCorners") != -1 ? "True" : "False"
-    Blockly.Python.addFunction("showBarcodesResult", `def showBarcodesResult(type1,type2):
-    global findBarcodes
-    for i in findBarcodes:
-        if type1:
-            canvas.draw_string((i["corners"][0][0]),(i["corners"][0][1]), (i["payload"]), scale = 1, color = (255,0,0) , thickness = 1)
-        if type2:
-            x1,y1 = i['corners'][0]   #访问字典的列表
-            x2,y2 = i['corners'][1]
-            x3,y3 = i['corners'][2]
-            x4,y4 = i['corners'][3]
-            canvas.draw_line(x1, y1, x2, y2, color = (0, 255, 0), thickness = 3)  
-            canvas.draw_line(x2, y2, x3, y3, color = (0, 255, 0), thickness = 3)  
-            canvas.draw_line(x3, y3, x4, y4, color = (0, 255, 0), thickness = 3)  
-            canvas.draw_line(x4, y4, x1, y1, color = (0, 255, 0), thickness = 3)
-`)
     // TODO: Assemble Python into code variable.
-    let code = ""
-    if (qrcodeResultAllBlock[0].id == block.id) {
-        code = `showBarcodesResult(${barcodesPayload},${barcodesCorners})
+    let code = `for i in findBarcodes:
+    canvas.draw_string((i["corners"][0][0]),(i["corners"][0][1]), (i["payload"]), scale = 1, color = (255,0,0) , thickness = 1)
+    x1,y1 = i['corners'][0]   #访问字典的列表
+    x2,y2 = i['corners'][1]
+    x3,y3 = i['corners'][2]
+    x4,y4 = i['corners'][3]
+    canvas.draw_line(x1, y1, x2, y2, color = (0, 255, 0), thickness = 3)  
+    canvas.draw_line(x2, y2, x3, y3, color = (0, 255, 0), thickness = 3)  
+    canvas.draw_line(x3, y3, x4, y4, color = (0, 255, 0), thickness = 3)  
+    canvas.draw_line(x4, y4, x1, y1, color = (0, 255, 0), thickness = 3)
 `
-    }
     return code
 };
 Blockly.Blocks['ai_vision_barcodes_get_info_result'] = {

+ 5 - 2
blockly/msg/js/en.js

@@ -4254,6 +4254,9 @@ Blockly.Msg.image_process_text_on_draw = "Draw";
 Blockly.Msg.image_text_on_draw = "Draw";
 Blockly.Msg.image_process_text_set_canvas_setup = "Set Canvas";
 Blockly.Msg.image_process_draw_qrcode = " QR code";
+Blockly.Msg.image_process_draw_qrcode_show = "Show QR Code";
+
+Blockly.Msg.image_process_text_recognize_qrcode = "Start Recognize QR Code";
 Blockly.Msg.image_process_draw_qr_code_size = "QR code size";
 
 Blockly.Msg.image_process_text_filled = "Filled";
@@ -4342,7 +4345,7 @@ Blockly.Msg.image_process_draw_line = " Line";
 Blockly.Msg.image_process_create_blank_canvas = "Create Blank Canvas:";
 Blockly.Msg.image_process_create_image_canvas = "Create Image Canvas:";
 Blockly.Msg.image_process_create_image_canvas_path = "Load Image from Path:";
-Blockly.Msg.image_process_show_canvas = "Show Canvas";
+Blockly.Msg.image_process_show_canvas = "Update the screen display content";
 Blockly.Msg.image_process_clear_canvas_1 = "Clear Canvas";
 Blockly.Msg.image_process_clear_canvas_2 = "All Content";
 
@@ -4497,7 +4500,7 @@ Blockly.Msg.ai_vision_detection_color_threshold_set_orange = "Orange";
 Blockly.Msg.ai_vision_qrcode_detected_result = "Get QR Code Detected Result";
 Blockly.Msg.ai_vision_apriltag_detected_result = "Get AprilTag Detected Result";
 Blockly.Msg.ai_vision_datamatrices_detected_result = "Get Data Matrices Detected Result";
-Blockly.Msg.ai_vision_barcode_detected_result = "Get Barcode Detected Result";
+Blockly.Msg.ai_vision_barcode_detected_result = "Start Barcode Detection";
 
 Blockly.Msg.ai_vision_qrcode_get_result = "Get the detected QR Code's ";
 Blockly.Msg.ai_vision_apriltag_get_result = "Get the detected AprilTag's ";

+ 4 - 2
blockly/msg/js/zh-hans.js

@@ -4213,6 +4213,8 @@ Blockly.Msg.image_process_text_on_draw = "上绘制";
 Blockly.Msg.image_text_on_draw = "绘制";
 Blockly.Msg.image_process_text_set_canvas_setup = "设置画布";
 Blockly.Msg.image_process_draw_qrcode = "二维码";
+Blockly.Msg.image_process_draw_qrcode_show = "显示二维码";
+Blockly.Msg.image_process_text_recognize_qrcode = "开始识别二维码";
 Blockly.Msg.image_process_draw_qr_code_size = "二维码大小";
 
 Blockly.Msg.image_process_text_filled = "实心";
@@ -4299,7 +4301,7 @@ Blockly.Msg.image_process_draw_line = "直线";
 Blockly.Msg.image_process_create_blank_canvas = "创建空白画布";
 Blockly.Msg.image_process_create_image_canvas = "创建图像画布";
 Blockly.Msg.image_process_create_image_canvas_path = "图像路径: ";
-Blockly.Msg.image_process_show_canvas = "显示画布";
+Blockly.Msg.image_process_show_canvas = "更新屏幕显示内容";
 Blockly.Msg.image_process_clear_canvas_1 = "清除画布";
 Blockly.Msg.image_process_clear_canvas_2 = "中的所有内容";
 Blockly.Msg.image_process_set_lcd_rotation = "旋转至";
@@ -4453,7 +4455,7 @@ Blockly.Msg.ai_vision_detection_color_threshold_set_orange = "橙色";
 Blockly.Msg.ai_vision_qrcode_detected_result = "中 QR 码的检测结果";
 Blockly.Msg.ai_vision_apriltag_detected_result = "中 AprilTag 的检测结果";
 Blockly.Msg.ai_vision_datamatrices_detected_result = "中数据矩阵 (Data Matrix) 的检测结果";
-Blockly.Msg.ai_vision_barcode_detected_result = "中条形码的检测结果";
+Blockly.Msg.ai_vision_barcode_detected_result = "开始识别条形码";
 
 Blockly.Msg.ai_vision_qrcode_get_result = "获取检测 QR 码的";
 Blockly.Msg.ai_vision_apriltag_get_result = "获取检测 AprilTag 的";

+ 4 - 2
blockly/msg/js/zh-hant.js

@@ -4677,6 +4677,8 @@ Blockly.Msg.image_process_text_on_draw = "上繪製";
 Blockly.Msg.image_text_on_draw = "繪製";
 Blockly.Msg.image_process_text_set_canvas_setup = "設定畫布";
 Blockly.Msg.image_process_draw_qrcode = "二維碼";
+Blockly.Msg.image_process_draw_qrcode_show = "顯示二維碼";
+Blockly.Msg.image_process_text_recognize_qrcode = "開始識別二維碼";
 Blockly.Msg.image_process_draw_qr_code_size = "二維碼大小";
 
 Blockly.Msg.image_process_text_filled = "實心";
@@ -4765,7 +4767,7 @@ Blockly.Msg.image_process_draw_line = "直線";
 Blockly.Msg.image_process_create_blank_canvas = "創建空白畫布";
 Blockly.Msg.image_process_create_image_canvas = "創建圖像畫布";
 Blockly.Msg.image_process_create_image_canvas_path = "圖像路徑: ";
-Blockly.Msg.image_process_show_canvas = "顯示畫布";
+Blockly.Msg.image_process_show_canvas = "更新熒幕顯示內容";
 Blockly.Msg.image_process_clear_canvas_1 = "清除畫布";
 Blockly.Msg.image_process_clear_canvas_2 = "中的所有內容";
 Blockly.Msg.image_process_set_lcd_rotation = "旋轉至";
@@ -4919,7 +4921,7 @@ Blockly.Msg.ai_vision_detection_color_threshold_set_orange = "橘色";
 Blockly.Msg.ai_vision_qrcode_detected_result = "中 QR 碼的檢測結果";
 Blockly.Msg.ai_vision_apriltag_detected_result = "中 AprilTag 的檢測結果";
 Blockly.Msg.ai_vision_datamatrices_detected_result = "中數據矩陣 (Data Matrix) 的檢測結果";
-Blockly.Msg.ai_vision_barcode_detected_result = "中條形碼的檢測結果";
+Blockly.Msg.ai_vision_barcode_detected_result = "開始條形碼檢測";
 
 Blockly.Msg.ai_vision_qrcode_get_result = "獲取檢測 QR 碼的";
 Blockly.Msg.ai_vision_apriltag_get_result = "獲取檢測 AprilTag 的";

+ 454 - 314
index.js

@@ -219,7 +219,6 @@ function getJsonData(filepath) {
 
 var isRunCodeData = '';
 var RunInterval = '';
-
 window.onload = async function () {
   $("#copyright_middle")[0].innerText = new Date().getFullYear()
   var url = window.location.hash.substring(1);
@@ -323,6 +322,22 @@ window.onload = async function () {
       // $('.translatable_close_editing')[0].style.display = "none"
     }
   })
+  // toggle-button-Connect
+
+  // $('#toggle-button-Connect').click(() => {
+  //   console.log($('#toggle-button-Connect')[0].checked)
+  //   if ($('#toggle-button-Connect')[0].checked) {
+  //     // $("#toggle-button-Connect")[0].checked = true
+  //     localStorage.setItem("SwitchConnect", true)
+  //     switch_connect = true
+  //     $('.circle_text')[0].innerText = _lang == "zh-hans" ? "自动" : _lang == "zh-hant" ? "自動" : "AT"
+  //   } else {
+  //     // $("#toggle-button-Connect")[0].checked = false
+  //     localStorage.setItem("SwitchConnect", false)
+  //     switch_connect = false
+  //     $('.circle_text')[0].innerText = _lang == "zh-hans" ? "手动" : _lang == "zh-hant" ? "手動" : "MT"
+  //   }
+  // })
   $('#toggle-button1').click(() => {
     if ($('#toggle-button1')[0].checked) {
       $('#image_transmission_canvas')[0].style.display = 'none';
@@ -456,17 +471,18 @@ window.onload = async function () {
     // $("#IP")[0].style.display = "block"
   }
 
-  // if (document.getElementById("v831_img_save")) {
-  //   document.getElementById("v831_img_save").onclick = function (e) {
-  //     console.log(this,e)
-  //     console.log("v831_img_save 被点击")
-  //   };
-  // }
-
-
   // 点击复制分享链接
   copyShare()
-
+  // 监听本地存储中是否自动连接
+  // if (localStorage.getItem("SwitchConnect") == "true" || localStorage.getItem("SwitchConnect") == null) {
+  //   $("#toggle-button-Connect")[0].checked = true
+  //   switch_connect = true
+  //   $('.circle_text')[0].innerText = _lang == "zh-hans" ? "自动" : _lang == "zh-hant" ? "自動" : "AT"
+  // } else {
+  //   $("#toggle-button-Connect")[0].checked = false
+  //   switch_connect = false
+  //   $('.circle_text')[0].innerText = _lang == "zh-hans" ? "手动" : _lang == "zh-hant" ? "手動" : "MT"
+  // }
   window.file_manger_modal = true
   document.getElementById("webadb_iframe").onload = function () {
     setInterval(function () {
@@ -581,59 +597,8 @@ window.onload = async function () {
     }, 1000)
   }
 
-  // 加载更新提示框
-  let updateData = await getJsonData('./update.json');
-  // 最新更新你内容
-  let updateNew = _lang == "zh-hans" ? updateData.updateNew.zhHans : _lang == "zh-hant" ? updateData.updateNew.zhHant : updateData.updateNew.en;
-  let isUpdate = localStorage.getItem('isUpdate') || 0
-  let blocklLis = "";
-  let exampleLis = "";
-  let noteLis = ""
-  for (let i = 0; i < updateNew.blocks.length; i++) {
-    let blockLi = `<li>${updateNew.blocks[i]}</li>`
-    blocklLis = blocklLis + blockLi
-  }
-  $('#blockLis').append(blocklLis)
-  for (let i = 0; i < updateNew.example.length; i++) {
-    let exampleLi = `<li>${updateNew.example[i]}</li>`
-    exampleLis = exampleLis + exampleLi
-  }
-  $('#exampleLis').append(exampleLis)
+  updateContentFun()
 
-  for (let i = 0; i < updateNew.note.length; i++) {
-    let noteLi = `<li>${updateNew.note[i]}</li>`
-    noteLis = noteLis + noteLi
-  }
-  $('#noteLis').append(noteLis)
-  $(".updateTime")[0].innerHTML = updateData.updateNew.time
-  // 历史更新
-  let updateDataOld = updateData.updateOld
-  let leftStr = ''
-  let noteStr = ''
-  for (let i = 0; i < updateDataOld.length; i++) {
-    let data = updateDataOld[i]
-    let time = `<h5>${data.time}</h5>`;
-    let updateData = _lang == "zh-hans" ? data.zhHans : _lang == "zh-hant" ? data.zhHant : data.en;
-    let blocklLisOld = ''
-    let exampleLisOld = ''
-    let noteLisOld = ''
-    for (let i = 0; i < updateData.blocks.length; i++) {
-      let blockLi = `<li>${updateData.blocks[i]}</li>`
-      blocklLisOld = blocklLisOld + blockLi
-    }
-    for (let i = 0; i < updateData.example.length; i++) {
-      let exampleLi = `<li>${updateData.example[i]}</li>`
-      exampleLisOld = exampleLisOld + exampleLi
-    }
-    for (let i = 0; i < updateData.note.length; i++) {
-      let noteLi = `<li>${updateData.note[i]}</li>`
-      noteLisOld = noteLisOld + noteLi
-    }
-    leftStr = leftStr + `${time}<li><span>${Ardublockly.LOCALISED_TEXT.updateblock}<ul class="updateContent">${blocklLisOld}</ul></li><li>${Ardublockly.LOCALISED_TEXT.updateexample}<ul class="updateContent">${exampleLisOld}</ul></li>`
-    noteStr = noteStr + `${time}${noteLisOld}`
-  }
-  $('#leftUpdateOld').append(leftStr)
-  $('#noteLisOld').append(noteStr)
   // $("#root").modal("open");
 }
 
@@ -946,6 +911,7 @@ function selectOnload() {
     if (a == 0) {
       $('#Serial_Interaction').css("display", 'inline-block')
       $('#IP').css('display', 'none')
+      // $("#SwitchConnect").css('display', 'inline-block')
     } else if (a == 2) {
       // console.log("蓝牙")webadb_add
       // deviceType = 2
@@ -956,6 +922,7 @@ function selectOnload() {
       // deviceType = 1
       $('#Serial_Interaction').css("display", 'none')
       $('#IP').css('display', 'block')
+      // $("#SwitchConnect").css('display', 'none')
       // 进行socket 连接
 
     }
@@ -1040,25 +1007,25 @@ function selectOnload() {
         for (var k = 0, len = exampleList.length; k < len; k++) {
           exampleList[k].style.display = "none";
         }
-        exampleList[13].style.display = "block";
+        exampleList[14].style.display = "block";
       }
       else if (this.id == 4) {
         for (var k = 0, len = exampleList.length; k < len; k++) {
           exampleList[k].style.display = "none";
         }
-        exampleList[15].style.display = "block";
+        exampleList[16].style.display = "block";
       }
       else if (this.id == 5) {
         for (var k = 0, len = exampleList.length; k < len; k++) {
           exampleList[k].style.display = "none";
         }
-        exampleList[22].style.display = "block";
+        exampleList[23].style.display = "block";
       }
       else if (this.id == 6) {
         for (var k = 0, len = exampleList.length; k < len; k++) {
           exampleList[k].style.display = "none";
         }
-        exampleList[27].style.display = "block";
+        exampleList[28].style.display = "block";
       }
       else {
         for (var k = 0, len = exampleList.length; k < len; k++) {
@@ -1125,9 +1092,20 @@ function selectOnload() {
 
 }
 
-
+// 获取浏览器类型
+function getBrowser() {
+  try{
+    const browserInfo = bowser.getParser(navigator.userAgent);
+    return browserInfo.getBrowserName();
+  }
+  catch (e) {
+    return "Chrome";
+  }
+  
+}
 function clickLoadingExample(name) {
-  console.log(name)
+  dataTrack("openExample",(name.split("/").length > 1 ? name.split("/")[1] : name.split("/")[0]))
+
   $('#select_Example_modal').modal('close');
   Ardublockly.alertExampleMessage(
     '',
@@ -1215,6 +1193,8 @@ function serialSwich(type) {
     $('#serial_plotter').addClass('switch_select')
     $('#help_documents').removeClass('switch_select')
     $('#help_documents').addClass('switch_box1')
+    $('.edit')[0].style.display = 'none';
+    // $('.edit')[1].style.display = 'none';
   } else if (type == 'help_document') {
     $('#repl_box').addClass('hidden')
     $('#python_box').addClass('hidden')
@@ -1641,21 +1621,13 @@ async function webadbConnect() {
     }
   }
 }
-function connectTest() {
-  // let fileCfgTest = `{ echo "" > /etc/wifi/fileCfgTest && echo "" > /root/fileCfgTest && echo "" > /home/fileCfgTest && echo "" > /tmp/fileCfgTest; } || { sync; fsck.ext4 -y /dev/root; (mount -o remount,rw -n /dev/root / ; mount -o remount,rw -n /dev/mmcblk0p4 / ; mount -o remount,rw -n /dev/mmcblk0p4 /mnt/UDISK ; mount -o remount,rw -n / / ; mount -o remount,rw -n /root / ; ) ; sync ; }`
-  setTimeout(() => {
-    let webadb_document = document.getElementById('webadb_iframe').contentWindow.getdevice()
-    webadb_document.device.subprocess.shell(Repair).then(res => {
-      res.stdout.reader.read().then(m => {
-        var str = Uint8ArrayToString(m.value);
-        console.log(str)
-        if (str.indexOf("/bin/sh") > -1 || str.indexOf("No such file or directory") > -1 || str.indexOf("Read-only file system") > -1) {
-          $("#webadbErro").css("display", "inline-block")
-          // webadb_document.device.subprocess.shell(`mount -o remount,rw /`)
-        }
-      })
-    })
-  }, 1000)
+async function connectTest() {
+  let isError = await repairFun()
+  if (isError) {
+    $("#webadbErro").css("display", "inline-block")
+  } else {
+    $("#webadbErro").css("display", "none")
+  }
 }
 function systemCommand(com) {
   if (deviceType == 1) {
@@ -1738,6 +1710,7 @@ async function fileBlobLoad(text, name, type) {
 }
 
 function uploadFilesCocoPi(file, fileOut) {
+
   document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/").then(s => {
     document.getElementById('webadb_iframe').contentWindow.upload(fileOut, "/root/").then(res => {
       $('.progress > .determinate').css('width', '50%');
@@ -1829,114 +1802,52 @@ function showServal(_data) {
     catch (e) {
     }
   } else {
-    let errMsg = ""
-    let errData = ""
-    let c = ''
+    // let errMsg = ""
+    // let errData = ""
+    let c = "";
     if (_data.indexOf(`camera`) == -1 && _data.length < 500) {
       if (_data.indexOf("/bin/sh:") > -1 || _data.indexOf("No such file or directory") > -1 || _data.indexOf("Read-only file system") > -1) {
-        $("#webadbErro").css("display", "inline-block")
-      }
-      let b = _data.split('\r\n')
-      for (let i = 0; i <= b.length - 1; i++) {
-        c += `<div>${b[i]}</div>`
+        $("#webadbErro").css("display", "inline-block");
       }
+      let b = _data.split('\r\n');
+      b.forEach((line) => {
+        c += `<div>${line}</div>`;
+      });
       $('#repl_box_content').append(c);
-      repl_box_contentheight = $("#repl_box_content")[0].scrollHeight;
+      let repl_box_contentheight = $("#repl_box_content")[0].scrollHeight;
       $("#repl_box_content").scrollTop(repl_box_contentheight);
     }
-    if (_data.indexOf(`NameError`) > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.error_pv}`)
-    } else if (_data.indexOf("IndentationError") > -1 || _data.indexOf("SyntaxError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.error_unindent}`)
-    } else if (_data.indexOf("IndexError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.IndexError}`)
-    } else if (_data.indexOf("AttributeError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.AttributeError}`)
-    } else if (_data.indexOf("TypeError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.error_unindent}`)
-    } else if (_data.indexOf("KeyError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.KeyError}`)
-    } else if (_data.indexOf("Read-only file system:") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.OsError}`)
-    } else if (_data.indexOf("FileNotFoundError") > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
-      }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.ENOEN}`)
-    } else if (_data.indexOf(`File "/tmp/event"`) > -1) {
-      setTimeout(() => {
-        $("#error-btn").css("display", "block")
-        $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
-      }, 500)
-      errMsg = _data.split('\r\n')
-      for (let i = 0; i <= errMsg.length - 1; i++) {
-        errData += `${errMsg[i]}\n`
+
+    const errors = {
+      'NameError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.error_pv,
+      'IndentationError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.error_unindent,
+      'SyntaxError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.error_unindent,
+      'IndexError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.IndexError,
+      'AttributeError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.AttributeError,
+      'TypeError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.error_unindent,
+      'KeyError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.KeyError,
+      'Read-only file system': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.OsError,
+      'FileNotFoundError': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.ENOEN,
+      'File "/tmp/event"': CCB.str_group.errSol + Ardublockly.LOCALISED_TEXT.error_unindent
+    };
+
+    for (const [errorType, localizedText] of Object.entries(errors)) {
+      if (_data.indexOf(errorType) > -1) {
+        displayError(_data.split('\r\n'), localizedText);
+        break;
       }
-      $("#err-msg").text(`${errData}\n${CCB.str_group.errSol}\n${Ardublockly.LOCALISED_TEXT.error_unindent}`)
     }
   }
 }
+function displayError(errMsg, localizedText) {
+  const errData = errMsg.join("\n");
+  $("#err-msg").text(`${errData}\n${localizedText}`);
+  dataTrack("error",`${errData}\n${localizedText}`)
+  setTimeout(() => {
+    $("#error-btn").css("display", "block");
+    $('.card-reveal').css({ 'display': 'block', 'transform': 'translateY(-100%)', 'padding': '8px 13px' });
+  }, 500);
+}
 var repl_box_contentheight = 0
 function getQrCode() {
   document.getElementById("codeImg").innerHTML = ""
@@ -2335,99 +2246,80 @@ const decounce = function (fn, delay) {
     }, delay)
   }
 }
-function uploadpyCocoPi() {
+async function uploadpyCocoPi() {
   $('.progress > .determinate').css('width', 0);
   $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution
-  setTimeout(async () => {
-    window.file_manger_modal = false
-    $("#runCode").addClass('disabled')
-    $("#uploadpy").addClass('disabled')
-    $("#resetDevice").addClass('disabled')
-    $("#poweroff").addClass('disabled')
-    $("#backHome").addClass('disabled')
-    // 上传
-    let text = pythonnewcode || Blockly.Python.workspaceToCode(blockpy.components.editor.blockly) || blockpy.components.editor.codeMirror.getValue()
-    // 开始上传
-    let textContain = fileBlobLoad(text, "user_latest_code.py", "text/plain")
-    if (deviceType == 1) {
-      sendWebsocket(text, 'upload')
-    } else if (deviceType == 2) {
-      $('.progress > .determinate').css('width', '50%');
-      $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%"
-      bluetoothUpload(text, true)
-    }
-    else {
-      // 转换完成后可以将file对象传给接口
-      textContain.then((res) => {
-        let file = res;
-        // window.stateapi.upload(file,"/root/")
-        $('.progress > .determinate').css('width', '50%');
-        $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%"
-        setTimeout(() => {
-          if (file) {
-            document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(Repair).then(r => {
-              setTimeout(function () {
-                r.stdout.reader.read().then(m => {
-                  var str = Uint8ArrayToString(m.value);
-                  if (str.indexOf("/bin/sh:") > -1 || str.indexOf("No such file or directory") > -1 || str.indexOf("Read-only file system") > -1) {
-                    $("#webadbErro").css("display", "inline-block")
-                    document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(`rm /root/user_latest_code.py`).then(s => {
-
-                      //错误处理
-                      document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(Repair1).then(r => {
-                        $("#webadbErro").css("display", "none")
-                        document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/").then(s => {
-                          $('.progress > .determinate').css('width', '100%');
-                          $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedSuccessfully + "100%"
-                        })
-                      }).catch(err => {
-                        $('.progress > .determinate').css('width', 0);
-                        $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedFail
-                      })
-                    })
-                  }
-                  else {
-                    $("#webadbErro").css("display", "none")
-                    // 没有错误处理
-                    document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/").then(s => {
-                      $('.progress > .determinate').css('width', '100%');
-                      $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedSuccessfully + "100%"
-                    })
-                  }
-                }).catch(n => {
-                  console.log(n)
-                })
-              }, 100)
-            }).catch(err => {
-              console.log(err)
-            })
-          } else {
-            $('.progress > .determinate').css('width', 0);
-            $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedFail
-          }
-          window.file_manger_modal = true
-          $("#runCode").removeClass('disabled')
-          $("#uploadpy").removeClass('disabled')
-          $("#resetDevice").removeClass('disabled')
-          $("#poweroff").removeClass('disabled')
-        }, 500)
-      })
+  window.file_manger_modal = false
+  $("#runCode").addClass('disabled')
+  $("#uploadpy").addClass('disabled')
+  $("#resetDevice").addClass('disabled')
+  $("#poweroff").addClass('disabled')
+  $("#backHome").addClass('disabled')
+  // 上传
+  let text = pythonnewcode || Blockly.Python.workspaceToCode(blockpy.components.editor.blockly) || blockpy.components.editor.codeMirror.getValue()
+  if (text == "\n") return true
+
+  dataTrack("upload","CocoPi-upload")
+  text = `import time
+import os
+os.system("i2cset -y 2 0x50 0x01 0x01")
+os.system("i2cset -y 2 0x50 0x00 0x01")
+time.sleep(0.05)
+${text}`
+  // 开始上传
+  let file = await fileBlobLoad(text, "user_latest_code.py", "text/plain")
+  $('.progress > .determinate').css('width', '50%');
+  $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%"
+  if (deviceType == 1) {
+    sendWebsocket(text, 'upload')
+  } else if (deviceType == 2) {
+    bluetoothUpload(text, true)
+  } else {
+    try {
+      let upload_file = await document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/")
+      console.log(upload_file)
+      if (upload_file) {
+        let isError = await repairFun()
+        if (isError) {
+          $("#webadbErro").css("display", "inline-block")
+          await document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(`rm /root/user_latest_code.py`)
+          await document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/")
+        } else {
+          $("#webadbErro").css("display", "none")
+        }
+      }
+      $('.progress > .determinate').css('width', '100%');
+      $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedSuccessfully + "100%"
+    } catch (err) {
+      console.log("上传发生错误:", err)
+      $('.progress > .determinate').css('width', 0);
+      $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedFail
     }
-  }, 1000)
+    setTimeout(function () {
+      window.file_manger_modal = true
+      $("#runCode").removeClass('disabled')
+      $("#uploadpy").removeClass('disabled')
+      $("#resetDevice").removeClass('disabled')
+      $("#poweroff").removeClass('disabled')
+    }, 500);
+  }
 }
 
-var Repair = `{ echo "" > /etc/wifi/fileCfgTest && echo "" > /root/fileCfgTest && echo "" > /home/fileCfgTest && echo "" > /tmp/fileCfgTest; } || { sync; fsck.ext4 -y /dev/root; fsck.ext4 -y /dev/mmcblk0p4; (mount -o remount,rw -n /dev/root / ; mount -o remount,rw -n /dev/mmcblk0p4 / ; mount -o remount,rw -n /dev/mmcblk0p4 /mnt/UDISK ; mount -o remount,rw -n / / ; mount -o remount,rw -n /root / ; ) ; fsck.ext4 -y /dev/root; fsck.ext4 -y /dev/mmcblk0p4; sync ; } ; { wpa_supplicant -i wlan0 -D nl80211 -c /etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets -B || (echo "" > /etc/wifi/wpa_supplicant.conf ;  wpa_supplicant -i wlan0 -D nl80211 -c /etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets -B) ; } ; `
-var Repair1 = Repair;
+var Repair = `{ echo "" > /etc/wifi/fileCfgTest && echo "" > /root/fileCfgTest && echo "" > /home/fileCfgTest && echo "" > /tmp/fileCfgTest; } `
+var Repair1 = `{ sync; fsck.ext4 -y /dev/root; fsck.ext4 -y /dev/mmcblk0p4; (mount -o remount,rw -n /dev/root / ; mount -o remount,rw -n /dev/mmcblk0p4 / ; mount -o remount,rw -n /dev/mmcblk0p4 /mnt/UDISK ; mount -o remount,rw -n / / ; mount -o remount,rw -n /root / ; ) ; fsck.ext4 -y /dev/root; fsck.ext4 -y /dev/mmcblk0p4; sync ; }`;
+var Repair2 = `{ wpa_supplicant -i wlan0 -D nl80211 -c /etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets -B || (echo "" > /etc/wifi/wpa_supplicant.conf ;  wpa_supplicant -i wlan0 -D nl80211 -c /etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets -B) ; }`;
 //`mount -o remount -rw /dev/mmcblk0p4 && fsck.ext4 -p /dev/root && mount -o remount -o rw /dev/root && mount -o remount,rw -n / && mount -o remount,rw -n /home && mount -o remount,rw -n /root && sleep 1;`
 async function runCocoPi() {
+
   let text = pythonnewcode || Blockly.Python.workspaceToCode(blockpy.components.editor.blockly) || blockpy.components.editor.codeMirror.getValue() || ""
   if (text == "\n") {
     return true
   }
+  dataTrack("run","CocoPi-run")
   text = `import time
 from maix import *
 import gc
-import os
+import os,sys
 import sys
 sys.path.append('/root/')
 from CocoPi import BUTTON
@@ -2533,53 +2425,83 @@ loop = asyncio.get_event_loop()
 loop.run_until_complete(tailf(filename))
 loop.close()
 `
+  let aa = text.indexOf("set_cocopi_agent_file_name")
   let fileOut = await fileBlobLoad(out, "out.py", "text/plain")
   $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution
-  if (deviceType == 1) {
-    // 无线连接
-    sendWebsocket(text, 'run')
-    $('.progress > .determinate').css('width', '50%');
-    // $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%"
-  } else if (deviceType == 2) {
-    $('.progress > .determinate').css('width', '20%');
-    $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "20%"
-    bluetoothUpload(text, false)
+  if (aa > -1) {
+    ai_agent(fileOut, text)
+  } else {
+    if (deviceType == 1) {
+      // 无线连接
+      sendWebsocket(text, 'run')
+      $('.progress > .determinate').css('width', '50%');
+      // $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%"
+    } else if (deviceType == 2) {
+      $('.progress > .determinate').css('width', '20%');
+      $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "20%"
+      bluetoothUpload(text, false)
+    }
+    else {
+      try {
+        // 修复分三步走
+        let isError = await repairFun()
+        if (isError) {
+          $("#webadbErro").css("display", "inline-block")
+        } else {
+          $("#webadbErro").css("display", "none")
+        }
+        await uploadFilesCocoPi(file, fileOut)
+      } catch (e) {
+        console.log("修复出现错误:", e)
+        window.file_manger_modal = true
+      }
+    }
   }
-  else {
-    document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(Repair).then(r => {
-      setTimeout(function () {
-        r.stdout.reader.read().then(m => {
-          var str = Uint8ArrayToString(m.value);
-          // 
-          if (str.indexOf("/bin/sh:") > -1 || str.indexOf("No such file or directory") > -1 || str.indexOf("Read-only file system") > -1) {
-            // uploadFilesCocoPi(file, fileOut)
-            $("#webadbErro").css("display", "inline-block")
-
-            // $('.progress > .determinate').css('width', 0);
-            // $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.ExecutedFail
-            // window.file_manger_modal = true
-            uploadFilesCocoPi(file, fileOut)
-            //错误处理
-            // document.getElementById('webadb_iframe').contentWindow.getdevice().device.subprocess.shell(Repair1).then(r => {
-            //   $("#webadbErro").css("display", "none")
-            //   uploadFilesCocoPi(file, fileOut)
-            // }).catch(err => {
-            // })
-          }
-          else {
-            // 没有错误处理
-            $("#webadbErro").css("display", "none")
-            uploadFilesCocoPi(file, fileOut)
-          }
-        }).catch(n => {
-          console.log(n)
-          window.file_manger_modal = true
-        })
-      }, 100)
-    }).catch(err => {
-      console.log(err)
-      window.file_manger_modal = true
-    })
+}
+async function repairFun() {
+  let isError = false
+  let repairList = [{}]
+  let commandResults
+  try {
+    let a1 = await executeShellCommand(Repair)
+    let m1 = await a1.stdout.reader.read()
+    let a2 = await executeShellCommand(Repair1)
+    let m2 = await a2.stdout.reader.read()
+    let a3 = await executeShellCommand(Repair2)
+    let m3 = await a3.stdout.reader.read()
+    let obj = [m1, m2, m3]
+    commandResults = await Promise.all(obj)
+  }
+  catch (e) {
+    console.log("修复出现错误:", e)
+  }
+  let str = commandResults.map(result => Uint8ArrayToString(result.value)).join("");
+  isError = await containsError(str)
+  return isError
+}
+async function executeShellCommand(command) {
+  try {
+    // 首先获取iframe元素和设备窗口,加入异常处理
+    const iframe = document.getElementById('webadb_iframe');
+    if (!iframe) {
+      throw new Error('WebADB iframe not found');
+    }
+    const contentWindow = iframe.contentWindow;
+    if (!contentWindow.getdevice) {
+      throw new Error('getdevice function not found in iframe contentWindow');
+    }
+    const device = contentWindow.getdevice().device;
+    if (!device || !device.subprocess || !device.subprocess.shell) {
+      throw new Error('Device or subprocess or shell function not found');
+    }
+
+    // 执行Shell命令
+    return await device.subprocess.shell(command);
+  } catch (error) {
+    console.error('Failed to execute shell command:', error);
+    // 根据实际情况,可以选择重新抛出异常,或者处理错误
+    // throw error; // 重新抛出异常,让调用者处理
+    return null; // 或者返回null,取决于业务逻辑
   }
 }
 // bledevice.gatt.connected 连接状态
@@ -2631,18 +2553,182 @@ function bluetoothRun() {
   })
 }
 
-var getBlocksByTypeName = function (typeName) {
-  var blocks = blockpy.components.editor.getBlocksFromXml().getElementsByTagName("block"); // 获取工作区中的所有块
-  var filteredBlocks = [];
-  // 遍历所有块,筛选出具有指定类型的块
-  for (var i = 0; i < blocks.length; i++) {
-      if (blocks[i].getAttribute("type") === typeName) {
-          filteredBlocks.push(blocks[i]);
-      }
+var switch_connect = false
+// 切换是否自动连接
+function SwitchConnect() {
+  console.log($("#SwitchConnectInput")[0].checked)
+  if ($("#SwitchConnectInput")[0].checked) {
+    $("#SwitchConnectInput")[0].checked = true
+    localStorage.setItem("SwitchConnect", true)
+    switch_connect = true
+  } else {
+    $("#SwitchConnectInput")[0].checked = false
+    localStorage.setItem("SwitchConnect", false)
+    switch_connect = false
   }
+}
+// agent 上传
+async function ai_agent(fileOut, text) {
+  let requestCocopi = `import requests
+import os
 
-  return filteredBlocks;
-};
+url = "http://gpt4.cocorobo.cn/mini_pi/upload_package"
+cmd="cat /sys/class/sunxi_info/sys_info"
+rec=os.popen(cmd).read()
+hwMac=rec[rec.find("sunxi_serial      : ")+20:rec.find("sunxi_serial      : ")+52]
+file_path = "/root/user/app/${localStorage.getItem("cocopi_agent_file_name").slice(1, -1)}.py"
+try:
+    # 以二进制模式打开文件
+    with open(file_path, 'rb') as file:
+        # 创建一个多部分表单实体
+        files = {'file': (file_path.split('/')[-1], file)}  
+        response = requests.post(url, files=files, data={"sn":hwMac})
+            
+        # 检查响应状态码
+        if response.status_code == 200:
+            print("文件上传成功",response.text)
+        else:
+            print(f"文件上传失败,服务器响应:{response.status_code}")
+except Exception as e:
+    print(f"上传过程中发生错误:{e}")
+
+`
+  console.log("requestCocopi", text)
+  let strText = `import traceback
+import logging
+import sys
+import os
+import time
+
+logger = logging.getLogger()
+logger.setLevel(logging.INFO)
+
+file_handler = logging.FileHandler('/root/output.log')
+file_handler.setLevel(logging.INFO)
+
+formatter = logging.Formatter('%(message)s')
+file_handler.setFormatter(formatter)
+
+logger.addHandler(file_handler)
+
+def log_output(*args, **kwargs):
+    output = ' '.join(map(str, args))
+    logger.info(output.strip(), **kwargs)
+
+sys.stderr.write = sys.stdout.write = log_output
+
+os.close(1)
+os.close(2)
+
+try:
+    source_code = r'''${requestCocopi}
+'''
+    exec(source_code)
+except Exception as e:
+    error_info = traceback.format_exc()
+    print(error_info)
+`;
+  let file = await fileBlobLoad(strText, "event", "text/plain")
+  let textFile = await fileBlobLoad(text, `${localStorage.getItem("cocopi_agent_file_name").slice(1, -1)}.py`, "text/plain")
+  console.log(textFile)
+
+  // 修复分三步走
+  try {
+    let isError = await repairFun()
+    if (isError) {
+      $("#webadbErro").css("display", "inline-block");
+    } else {
+      $("#webadbErro").css("display", "none");
+    }
+    await uploadFilesCocoPiAgent(file, fileOut, textFile);
+  }
+  catch (err) {
+    console.log("错误:", err)
+    window.file_manger_modal = true
+  }
+}
+// 检测是否报错
+function containsError(str) {
+  const errorStrings = ["/bin/sh:", "No such file or directory", "Read-only file system"];
+  return errorStrings.some(errStr => str.includes(errStr));
+}
+// 上传文件
+async function uploadFilesCocoPiAgent(file, fileOut, text) {
+  try {
+    await document.getElementById('webadb_iframe').contentWindow.upload(file, "/root/");
+    await document.getElementById('webadb_iframe').contentWindow.upload(fileOut, "/root/");
+    await document.getElementById('webadb_iframe').contentWindow.upload(text, "/root/user/app/");
+    $('.progress > .determinate').css('width', '50%');
+    $("#status_txt")[0].innerHTML = Ardublockly.LOCALISED_TEXT.InExecution + "50%";
+    clearInterval(RunInterval);
+    if (isRunCodeData && typeof isRunCodeData.kill === 'function') {
+      await isRunCodeData.kill();
+    }
+    await run_user_lastet_code();
+  }
+  catch (e) {
+    console.error('上传或执行过程中发生错误:', err);
+    window.file_manger_modal = true;
+  }
+}
+
+
+async function updateContentFun() {
+  let a = new Date().getTime()
+  // 加载更新提示框
+  let updateData = await getJsonData('./update.json');
+  // 最新更新你内容
+  let updateNew = _lang == "zh-hans" ? updateData.updateNew.zhHans : _lang == "zh-hant" ? updateData.updateNew.zhHant : updateData.updateNew.en;
+  let isUpdate = localStorage.getItem('isUpdate') || 0
+  let blocklLis = "";
+  let exampleLis = "";
+  let noteLis = ""
+  for (let i = 0; i < updateNew.blocks.length; i++) {
+    let blockLi = `<li>${updateNew.blocks[i]}</li>`
+    blocklLis = blocklLis + blockLi
+  }
+  $('#blockLis').append(blocklLis)
+  for (let i = 0; i < updateNew.example.length; i++) {
+    let exampleLi = `<li>${updateNew.example[i]}</li>`
+    exampleLis = exampleLis + exampleLi
+  }
+  $('#exampleLis').append(exampleLis)
+
+  for (let i = 0; i < updateNew.note.length; i++) {
+    let noteLi = `<li>${updateNew.note[i]}</li>`
+    noteLis = noteLis + noteLi
+  }
+  $('#noteLis').append(noteLis)
+  $(".updateTime")[0].innerHTML = updateData.updateNew.time
+  // 历史更新
+  let updateDataOld = updateData.updateOld
+  let leftStr = ''
+  let noteStr = ''
+  for (let i = 0; i < updateDataOld.length; i++) {
+    let data = updateDataOld[i]
+    let time = `<h5>${data.time}</h5>`;
+    let updateData = _lang == "zh-hans" ? data.zhHans : _lang == "zh-hant" ? data.zhHant : data.en;
+    let blocklLisOld = ''
+    let exampleLisOld = ''
+    let noteLisOld = ''
+    for (let i = 0; i < updateData.blocks.length; i++) {
+      let blockLi = `<li>${updateData.blocks[i]}</li>`
+      blocklLisOld = blocklLisOld + blockLi
+    }
+    for (let i = 0; i < updateData.example.length; i++) {
+      let exampleLi = `<li>${updateData.example[i]}</li>`
+      exampleLisOld = exampleLisOld + exampleLi
+    }
+    for (let i = 0; i < updateData.note.length; i++) {
+      let noteLi = `<li>${updateData.note[i]}</li>`
+      noteLisOld = noteLisOld + noteLi
+    }
+    leftStr = leftStr + `${time}<li><span>${Ardublockly.LOCALISED_TEXT.updateblock}<ul class="updateContent">${blocklLisOld}</ul></li><li>${Ardublockly.LOCALISED_TEXT.updateexample}<ul class="updateContent">${exampleLisOld}</ul></li>`
+    noteStr = noteStr + `${time}${noteLisOld}`
+  }
+  $('#leftUpdateOld').append(leftStr)
+  $('#noteLisOld').append(noteStr)
+}
 /*import os
 os.system("cd root/user  && mkdir model && chmod 777 *")
 os.system("cd /")
@@ -2673,4 +2759,58 @@ for event in mouse.read_loop():
         elif event.code == ecodes.REL_Y:
             print(f"Mouse Y movement: {event.value}")
 */
+// 获取网络ip 信息
+function ipJson(data) {
+  window.ipJson = data
+}
 
+// 数据埋点函数
+function dataTrack(type,content) {
+  try {
+    let params = {}
+    if (CCB.UserInfo) {
+      params = {
+        userid: CCB.UserInfo.data.userid,
+        username: CCB.UserInfo.data.username,
+        accountNumber: CCB.UserInfo.data.username,
+        org: CCB.UserInfo.data.defaultSchool,
+        school: CCB.UserInfo.data.defaultSchool,
+        browser: getBrowser(),
+        userTime: new Date().toLocaleString("zh-cN", { hour12: false, timeZone: "Asia/shanghai" }),
+        loadTime: "",
+        endTime: "",
+        object: JSON.stringify({ type,content }),
+        status: "success",
+        ip: window.ipJson && window.ipJson.ip || "",
+        ipAddress: window.ipJson && window.ipJson.addr || ""
+      }
+    } else {
+      params = {
+        userid: (window.ipJson && window.ipJson.ip.replaceAll(".","")) || "",
+        username: "",
+        accountNumber: "",
+        org: window.ipJson && window.ipJson.addr || "",
+        school: "",
+        browser: getBrowser(),
+        userTime: new Date().toLocaleString("zh-cN", { hour12: false, timeZone: "Asia/shanghai" }),
+        loadTime: "",
+        endTime: "",
+        object: JSON.stringify({ type,content }),
+        status: "success",  
+        ip: window.ipJson && window.ipJson.ip || "",
+        ipAddress: window.ipJson && window.ipJson.addr || ""
+      }
+    }
+
+    $.ajax(`https://pbl.cocorobo.cn/api/mongo/updateUserData2P`, {
+      method: 'POST',
+      data: params,
+      success: function (res) {
+        console.log("成功", res)
+
+      }
+    })
+  } catch (error) {
+    console.log("失败", error)
+  }
+}

+ 1 - 5
src/python/AI/人脸识别.xml

@@ -43,11 +43,7 @@
                 <next>
                   <block type="face_recognition_data_load" id="47(H/I_Lx,P99}aVU5?S">
                     <next>
-                      <block type="face_recognition_if_face" id="mD.,N+8B%47fGAZ*hd2G">
-                        <next>
-                          <block type="ai_lcd_showcarvas_set_display" id="G53S9xg,q:=U=lWRg95p"></block>
-                        </next>
-                      </block>
+                      <block type="ai_lcd_showcarvas_set_display" id="G53S9xg,q:=U=lWRg95p"></block>
                     </next>
                   </block>
                 </next>

+ 12 - 16
src/python/video/play_vidoe.xml

@@ -1,32 +1,28 @@
 <xml xmlns="http://www.w3.org/1999/xhtml" type="IoT">
-  <block type="ai_video_set_init" id="s)iT]W_MIi^-OsA@9wsy" x="230" y="140">
+  <block type="ai_video_set_init" id="S3c~R6}J(Ed^P/6aUPp6" x="-8" y="-82">
     <next>
-      <block type="controls_repeat_forever" id="Y2HxoM|F816klda];L_J">
+      <block type="controls_repeat_forever" id=".lx4?i7.awh[D@Vp/.~c">
         <statement name="DO">
-          <block type="ai_video_set" id="n(I|j8=hj1EZdRYZg.;D">
+          <block type="ai_video_set" id="MP9|L.bB?TE8V6*6}yj:">
             <value name="path">
-              <shadow type="text" id="OymB=!5;Rgl$)^fiUe5E">
-                <field name="TEXT">/root/preset/video/output_240_240.mp4</field>
+              <shadow type="text" id="eL*9QWc-vHS[~G4hyi`d">
+                <field name="TEXT">/root/user/video/record.mp4</field>
               </shadow>
             </value>
             <next>
-              <block type="controls_forEach" id="xwO7XC6WCon;-@AiW5Tq">
+              <block type="controls_forEach" id="/sm`;caC_f)FTa;%A/lt">
                 <field name="VAR">i</field>
                 <value name="LIST">
-                  <block type="ai_video_set_stats" id="U.UmMvlIig$;4r1GXTuE"></block>
+                  <block type="ai_video_set_stats" id="c3|!VNPZV_YpV$UJ@i.g"></block>
                 </value>
                 <statement name="DO">
-                  <block type="controls_if" id="?~Fh01G/_bL:hQ60I*Sx">
-                    <value name="IF0">
-                      <block type="ai_v831_button_read_pressed" id="x0MZmu*4bbTnsh+!3O!z">
-                        <field name="button_type">C</field>
-                      </block>
-                    </value>
-                    <statement name="DO0">
-                      <block type="ai_video_stop_play" id="#5,QjWSS+?){2._6e$@]"></block>
+                  <block type="ai_v831_button_read_pressed" id="GatOqt1YVL5fBjVQ@unF">
+                    <field name="button_type">C</field>
+                    <statement name="input">
+                      <block type="ai_video_stop_play" id=")xHYIitk}ubGKUi%YJrS"></block>
                     </statement>
                     <next>
-                      <block type="ai_video_set_play" id="3AgsrkDB^NVNa*oY9m%z">
+                      <block type="ai_video_set_play" id="O2#hLgn,SEp|JSgp-xZd">
                         <field name="varitem">i</field>
                       </block>
                     </next>

+ 0 - 92
src/python/video/视频播放.xml

@@ -1,92 +0,0 @@
-<xml xmlns="http://www.w3.org/1999/xhtml" type="IoT">
-  <block type="ai_video_set_init" id="s)iT]W_MIi^-OsA@9wsy" x="219" y="80">
-    <next>
-      <block type="variables_set" id="F+*Q[~=Z}mnY?QH|d4^-">
-        <field name="VAR">stop_video</field>
-        <value name="VALUE">
-          <shadow type="math_number" id="/IJd@2Vx,eJI)hjF{GMM">
-            <field name="NUM">0</field>
-          </shadow>
-        </value>
-        <next>
-          <block type="controls_repeat_forever" id="Y2HxoM|F816klda];L_J">
-            <statement name="DO">
-              <block type="ai_video_set" id="n(I|j8=hj1EZdRYZg.;D">
-                <value name="path">
-                  <shadow type="text" id="OymB=!5;Rgl$)^fiUe5E">
-                    <field name="TEXT">/root/preset/video/output_240_240.mp4</field>
-                  </shadow>
-                </value>
-                <next>
-                  <block type="controls_forEach" id="xwO7XC6WCon;-@AiW5Tq">
-                    <field name="VAR">i</field>
-                    <value name="LIST">
-                      <block type="ai_video_set_stats" id="U.UmMvlIig$;4r1GXTuE"></block>
-                    </value>
-                    <statement name="DO">
-                      <block type="ai_v831_button_read_released" id="#B~RnbaVk5FpBMR*]Vy(">
-                        <field name="button_type">C</field>
-                        <statement name="input">
-                          <block type="variables_set" id="=K;Yp$-$?Th?Yf.$wr`Y">
-                            <field name="VAR">stop_video</field>
-                            <value name="VALUE">
-                              <shadow type="math_number" id="A)*J$;wiuui~^-%AN@2O">
-                                <field name="NUM">1</field>
-                              </shadow>
-                            </value>
-                          </block>
-                        </statement>
-                        <next>
-                          <block type="ai_v831_button_read_released" id="`5PB7}Nm_;uMU`qvw4iN">
-                            <field name="button_type">D</field>
-                            <statement name="input">
-                              <block type="variables_set" id="`{e9.GDvpcdP#S|C72/Y">
-                                <field name="VAR">stop_video</field>
-                                <value name="VALUE">
-                                  <shadow type="math_number" id="j:u$p5HIdWe(C{0-O!cb">
-                                    <field name="NUM">0</field>
-                                  </shadow>
-                                </value>
-                              </block>
-                            </statement>
-                            <next>
-                              <block type="controls_if" id="ZY1PAOZ,RXuLyCTVPJ}e">
-                                <value name="IF0">
-                                  <block type="logic_compare" id="-F7E8gkTMuW/.m|^HS*t">
-                                    <field name="OP">EQ</field>
-                                    <value name="A">
-                                      <block type="variables_get" id="kD*_|-XFmfd1)2C@CLL^">
-                                        <field name="VAR">stop_video</field>
-                                      </block>
-                                    </value>
-                                    <value name="B">
-                                      <block type="math_number" id="x@eS6]I%UZ_tNt*OWvyK">
-                                        <field name="NUM">1</field>
-                                      </block>
-                                    </value>
-                                  </block>
-                                </value>
-                                <statement name="DO0">
-                                  <block type="ai_video_stop_play" id="#5,QjWSS+?){2._6e$@]"></block>
-                                </statement>
-                                <next>
-                                  <block type="ai_video_set_play" id="3AgsrkDB^NVNa*oY9m%z">
-                                    <field name="varitem">i</field>
-                                  </block>
-                                </next>
-                              </block>
-                            </next>
-                          </block>
-                        </next>
-                      </block>
-                    </statement>
-                  </block>
-                </next>
-              </block>
-            </statement>
-          </block>
-        </next>
-      </block>
-    </next>
-  </block>
-</xml>

+ 1 - 7
src/python/图像处理/二维码识别.xml

@@ -6,14 +6,8 @@
           <block type="ai_vision_find_qrcode" id="Ksi[LEH8Sp`9[4T0w+at">
             <next>
               <block type="ai_vision_find_qrcode_result" id="VlNpsCU$Dy{VvK#kxBU|">
-                <field name="qrcode_result">SourceText</field>
                 <next>
-                  <block type="ai_vision_find_qrcode_result" id="wGLyY-HW1(U~St|*l6nj">
-                    <field name="qrcode_result">CheckBox</field>
-                    <next>
-                      <block type="ai_lcd_showcarvas_set_display" id="V*0L{lbS!vap6~qBB55+"></block>
-                    </next>
-                  </block>
+                  <block type="ai_lcd_showcarvas_set_display" id="V*0L{lbS!vap6~qBB55+"></block>
                 </next>
               </block>
             </next>

+ 5 - 21
src/python/图像处理/获取条形码.xml

@@ -1,29 +1,13 @@
 <xml xmlns="http://www.w3.org/1999/xhtml" type="IoT">
-  <block type="controls_repeat_forever" id="MiF-ngsfEtU#I{-EVeK]" x="354" y="129">
+  <block type="controls_repeat_forever" id="8{M85LykUWXhtk4]1Mzo" x="306" y="-333">
     <statement name="DO">
-      <block type="ai_camera_snapshot" id="YkGz:}!-V$Tx%raRdt{h">
+      <block type="ai_camera_snapshot" id="|O}93OKa;w5H@dN6O#6*">
         <next>
-          <block type="ai_vision_find_barcodes" id="O#!u#-Bdq*wOS7cRCIS3">
+          <block type="ai_vision_find_barcodes" id="p/]C0B%7[f9X95E-=hZy">
             <next>
-              <block type="ai_vision_barcodes_get_info" id="e=zLTxk$F^fUxI_GZX;(">
-                <field name="get_info">barcodesPayload</field>
+              <block type="ai_vision_barcodes_get_info" id="$@yFgYbsoZWjq(#E@72k">
                 <next>
-                  <block type="ai_vision_barcodes_get_info" id="2kNym?z+-K{I$E%H$`oH">
-                    <field name="get_info">barcodesCorners</field>
-                    <next>
-                      <block type="serial_comm_print" id="X=qBcY4CIot9Ly~=l)sO">
-                        <value name="serial_comm_input">
-                          <shadow type="text" id="VS^6lZWUd=EU6M3ev1E|">
-                            <field name="TEXT">Hello World!</field>
-                          </shadow>
-                          <block type="ai_vision_barcodes_get_info_result" id="rN5d,WIIBzrh5tjOeX5-"></block>
-                        </value>
-                        <next>
-                          <block type="ai_lcd_showcarvas_set_display" id="%{.l-j]~4_!Nt$-VF:.*"></block>
-                        </next>
-                      </block>
-                    </next>
-                  </block>
+                  <block type="ai_lcd_showcarvas_set_display" id="V*0L{lbS!vap6~qBB55+"></block>
                 </next>
               </block>
             </next>