diff --git a/release/ww/ww_server.js b/release/ww/ww_server.js
new file mode 100644
index 0000000000000000000000000000000000000000..47bce88d6c210ad979a62268c9ff189d5c071bdb
--- /dev/null
+++ b/release/ww/ww_server.js
@@ -0,0 +1,611 @@
+/**
+ * 沃特沃德串口屏协议服务
+ *
+ * 版本:v0.1
+ * 开发者
+ * 历史:
+ *
+ */
+
+/**
+ * 串口协议格式说明:
+ *
+ * 大端格式(包括参数内容也使用大端)
+ *
+ * 协议头:0x8081
+ * 数据长度:2字节,不包括协议头和数据长度本身
+ * 函数码:1字节,函数api索引
+ * 参数个数:1字节
+ * 参数内容:
+ * {
+ *   参数类型:1字节,0=int32,1=float,2=double,3=字符串对象(字符串对象包括2字节的长度和内容,utf8格式,0结尾,长度包括0终止符)
+ * }
+ * crc校验:2字节
+ *
+ *
+ * 返回数据格式:与发送数据格式相同,只是参数个数只能为1个。
+ */
+
+// console.log = function () {};
+// console.trace = function () {};
+var lvgl = require("@native.lvgl7");
+var router = require("@system.router");
+var process = require("@system.process");
+var dpkt = require("dpkt.js");
+var wwProto = globalThis["@native.ww"];
+var image = require("@native.image");
+var librtc = require("rtc.js");
+var os = require("@system.os");
+var rebootdevice = require("rebootdevice.js");
+//nodejs调试模式
+var NodeJs = 0;
+// 当前页面ID
+var g_pageNum;
+
+var WW_POINT_RATE = 0.69;
+var WW_POINT_LINE_X = 0.2;
+var WW_POINT_LINE_B = -0.8;
+var WW_POINT_NUM = 8;
+var WW_FONT_RATE = 1.0;
+var WW_FONT_HIGHT = 1.2;
+var WW_TEXTINPUT_TOP = -5;
+
+var WW_TOPEquation_A = 0.0078125; // 1/128
+var WW_TOPEquation_B = -0.40625; // -13/32
+var WW_TOPEquation_C = 7.25; // 29/4
+var WW_TOPEquation_D = -40; // -40
+
+//后面可以配置参数
+var opt_clear_all_images = true;
+
+function checkDialogState() {
+  if (isDialogShowing == 2) {
+    var pageName = keyboardRule["keyboardId"];
+    restoreDataInputPosition();
+    router.hideDialog("page" + pageName);
+  }
+}
+function onShow() {
+  // console.log("{onShow} debug pos 0 " + isDialogShowing);
+  this.$onShow();
+  // console.log("{onShow} debug pos 1 ");
+  if (opt_clear_all_images && isDialogShowing != 1) {
+    // console.log("{onShow} debug pos 2 ");
+    var imageCache = this.$imageCache;
+    var keys = Object.keys(imageCache);
+    for (var i = 0; i < keys.length; i++) {
+      var path = keys[i];
+      var img_dsc_t = imageCache[path];
+      if (!invoke_is_null(img_dsc_t)) {
+        image.freeImage(img_dsc_t);
+        imageCache[path] = undefined;
+      }
+    }
+  }
+  // console.log("{onShow} debug pos 3 ");
+  // console.log("{push page} 1");
+  var nodes = this.$el;
+  if (Array.isArray(nodes)) {
+    // console.log("{onShow} debug pos 4 ");
+    // console.log("{push page} 2");
+    var length = nodes.length;
+    for (var i = 0; i < length; i++) {
+      // console.log("{push page}i=" + i);
+      var node = nodes[i];
+      var attributes = node.attributes;
+      // console.log("{push page}id=" + attributes.id);
+      if (node.name == "image") {
+        // console.log("{push page} image");
+        var obj = node.nativePtr;
+        var widgetType = attributes.widgetType;
+        if (widgetType == "varIcon") {
+          // console.log(
+          //   "{push page}id=" +
+          //     attributes.id +
+          //     " is var icon,path=" +
+          //     attributes.src
+          // );
+          os.setBlackAsTransparent(true);
+        }
+        var imageCache = this.$imageCache;
+        // console.log("cache keys=" + Object.keys(imageCache));
+        // console.log("cache values=" + Object.values(imageCache));
+        this.$image_set_src(obj, attributes.src);
+        this.$setBackgroundColor(attributes.id, "transparent");
+        this.$show(attributes.id);
+        os.setBlackAsTransparent(false);
+      }
+    }
+  }
+  // console.log("{onShow} debug quit ");
+}
+
+var pagePushing = 0;
+var router_push = router.push;
+router.router_push = router_push;
+router.push = function (obj, backend) {
+  // console.log("{router push} enter.. ");
+  checkDialogState();
+  // console.log("{router_push} debug pos 0 ");
+  pagePushing = 1;
+  this.router_push(obj, backend);
+  // console.log("{router_push} finished ");
+
+  if (this.currentPage.$indexObj.$onShow == undefined) {
+    var tempOnShow = this.currentPage.$indexObj.onShow;
+    this.currentPage.$indexObj.$onShow = tempOnShow;
+    this.currentPage.$indexObj.onShow = onShow;
+  }
+
+  pagePushing = 0;
+  // console.log("{router_push} quit.. ");
+};
+
+var adjustKeyboardCoorId = undefined;
+
+var dialog_obj = lvgl.lv_cont_create(lvgl.lv_scr_act(), null);
+lvgl.lv_obj_set_style_local_border_width(dialog_obj, 0, 0, 0);
+var isDialogShowing = 0;
+router.showDialog = function (pageName, x, y, width, height, moveX, moveY) {
+  isDialogShowing = 1;
+  var page = router.pages[pageName];
+  if (page == undefined) {
+    opt_clear_all_images = false;
+    router.push(
+      {
+        path: pageName,
+      },
+      false
+    );
+    opt_clear_all_images = true;
+  }
+  isDialogShowing = 2;
+  page = router.pages[pageName];
+  if (page == undefined) return;
+
+  var nodes = page.$indexObj.$el;
+  if (Array.isArray(nodes)) {
+    var length = nodes.length;
+    for (var i = 0; i < length; i++) {
+      var node = nodes[i];
+      var attributes = node.attributes;
+      if (node.name == "image") {
+        var obj = node.nativePtr;
+        page.$indexObj.$image_set_src(obj, attributes.src);
+      }
+    }
+  }
+
+  // var rootObj = page.rootObj;
+  // lvgl.lv_obj_move_foreground(rootObj);
+  // lvgl.lv_obj_set_hidden(rootObj, false);
+  // // console.log("x=" + x);
+  // // console.log("y=" + y);
+  // lvgl.lv_obj_set_left(rootObj, x);
+  // lvgl.lv_obj_set_top(rootObj, y);
+  page.$indexObj.onShow();
+
+  // adjustKeyboardCoorId = setTimeout(adjustKeyboardCoor, 10, [pageName, width, height, moveX, moveY])
+  adjustKeyboardCoorId = setTimeout(function () {
+    var router = require("@system.router");
+    page = router.pages[pageName];
+    // // console.log("pageName=" + pageName);
+    // // console.log("page:" + Object.keys(page));
+    var indexObj = page.$indexObj;
+    // // console.log("indexObj:" + Object.keys(indexObj));
+    // var elementList = indexObj.$el
+    // console.log("elementList:" + elementList)
+
+    //example:
+    lvgl.lv_obj_set_parent(dialog_obj, router.currentPage.$indexObj.$rootObj);
+    lvgl.lv_obj_set_x(dialog_obj, x); // do it yourself
+    lvgl.lv_obj_set_y(dialog_obj, y); // do it yourself
+    // // console.log("width=" + width);
+    // // console.log("height=" + height);
+    lvgl.lv_obj_set_width(dialog_obj, width); // do it yourself
+    lvgl.lv_obj_set_height(dialog_obj, height); // do it yourself
+
+    lvgl.lv_obj_set_parent(page.$indexObj.$rootObj, dialog_obj);
+    // // console.log("moveX=" + moveX);
+    // // console.log("moveY=" + moveY);
+    lvgl.lv_obj_set_x(page.$indexObj.$rootObj, moveX); // do it yourself
+    lvgl.lv_obj_set_y(page.$indexObj.$rootObj, moveY); // do it yourself
+    // lvgl.lv_obj_set_x(page.$indexObj.$rootObj, 0);// do it yourself
+    // lvgl.lv_obj_set_y(page.$indexObj.$rootObj, 0);// do it yourself
+    lvgl.lv_obj_move_foreground(page.$indexObj.$rootObj);
+    lvgl.lv_obj_move_foreground(dialog_obj);
+    lvgl.lv_obj_set_hidden(dialog_obj, false);
+    lvgl.lv_obj_set_hidden(page.$indexObj.$rootObj, false);
+    lvgl.lv_obj_invalidate(dialog_obj);
+
+    // if (elementList) {
+    //     var nodes = page.$indexObj.$nodes;
+    //     if (Array.isArray(nodes)) {
+    // console.log("Array.isArray(nodes)")
+    //         var length = nodes.length;
+    //         for (var i = 0; i < length; i++) {
+    //             var node = nodes[i];
+    //             var attributes = node.attributes;
+    // console.log("node id=" + node.attributes.id)
+    //             if (node.name == 'image') {
+    //                 // var  id=node.attributes["id"]
+    //                 // indexObj.$foreground(id)
+    //                 // indexObj.$imageRender(id, attributes.src)
+    //                 var obj = node.nativePtr;
+    //                 indexObj.$image_set_src(obj, attributes.src);
+    //                 if (attributes.var_address == "0xFFFF") {
+    // console.log("moveX=" + moveX)
+    // console.log("moveY=" + moveY)
+    //                     indexObj.$setX(attributes.id, moveX)
+    //                     indexObj.$setY(attributes.id, moveY)
+    //                 }
+    //             }
+    //             if (attributes.id == pageName) {
+    // console.log("width=" + width)
+    // console.log("height=" + height)
+    //                 indexObj.$setWidth(attributes.id, width)
+    //                 indexObj.$setHeight(attributes.id, height)
+    //             }
+    //         }
+    //     }
+    // }
+    clearTimeout(adjustKeyboardCoorId);
+    // // console.log("=========showDialog quit..");
+  }, 50);
+};
+
+router.hideDialog = function (pageName) {
+  // // console.log("pageName:" + pageName);
+  isDialogShowing = 0;
+  var page = router.pages[pageName];
+  if (page == undefined) return;
+  page.$indexObj.onHide();
+  var rootObj = page.rootObj;
+  lvgl.lv_obj_set_hidden(rootObj, true);
+  lvgl.lv_obj_move_background(rootObj);
+  lvgl.lv_obj_set_hidden(dialog_obj, true);
+
+  updatePageDataId = setTimeout(function () {
+    refreshPageMessage();
+    clearTimeout(updatePageDataId);
+  }, 50);
+};
+
+function initEventLister() {
+  var EventEmitter = require("@system.events");
+  globalThis.eventEmitter = new EventEmitter();
+}
+initEventLister();
+
+/**windows下调试配置
+ * 1、串口号
+ */
+var winDefaultPort = "COM4";
+var uartWW = undefined;
+
+function TextDecoder(encoding) {
+  if (encoding == undefined) this.encoding = "utf-8";
+  else this.encoding = encoding;
+}
+
+TextDecoder.prototype.decode = function (data) {
+  var os = require("@system.os");
+  return os.decode(this.encoding, data.cdata(), data.length);
+};
+
+var ww_regs;
+
+/**
+ *  串口设置相关
+ */
+function setup(port, baud) {
+  //读取配置文件
+  var cfg = loading(__dirname + "/config.json");
+  if (cfg != undefined) {
+    for (var cnt = 0; cnt < cfg.module.length; cnt++) {
+      var req = require(cfg.module[cnt].file);
+      if (cfg.module[cnt].param != undefined) {
+        req.init(cfg.module[cnt].param);
+      } else {
+        req.init();
+      }
+    }
+  }
+  //串口打开后,解析数据协议,调用protoHandler
+  var uart = require("uart.js");
+  if (process.platform == "win32") {
+    port = winDefaultPort;
+    console.log("port=" + port);
+    console.log("baud=" + baud);
+    uartWW = uart.open({
+      path: port,
+      baudRate: baud,
+      dataBits: 8,
+      stopbits: 1,
+      parity: 0,
+      mode: "text", // mode="text/json/bin"
+    });
+
+    setInterval(function () {
+      uartWW.read();
+    }, 100);
+  } else {
+    console.log("port=" + port);
+    console.log("baud=" + baud);
+    uartWW = uart.open_async({
+      path: port,
+      baudRate: baud,
+      dataBits: 8,
+      stopbits: 1,
+      parity: 0,
+      mode: "text",
+      timeout: 10,
+    });
+  }
+  uartWW.on("data", getUartData);
+}
+
+/**
+ *  收到串口数据
+ */
+function getUartData(data, length) {
+  if (data.length == 0) {
+    // data.print()
+    data.free();
+    return;
+  }
+  // console.log(showMemInfo())
+  data.print();
+  var currentPage = router.currentPage;
+  if (currentPage == undefined) {
+    wwProto.handle(undefined, data.cdata(), data.length, handleCallback);
+    data.free();
+    return;
+  }
+
+  var indexObj = currentPage.$indexObj;
+  wwProto.handle(indexObj, data.cdata(), data.length, handleCallback);
+  data.free();
+}
+
+var funcAPIs = undefined;
+var cached_values = undefined;
+
+function push_page(pageId) {
+  router.push({
+    path: "page" + pageId,
+  });
+}
+
+function push_page_and_refresh_caches(pageId) {
+  var currentPage = router.currentPage;
+  router.push({
+    path: "page" + pageId,
+  });
+  var indexObj = currentPage.$indexObj;
+  for (var i in cached_values) {
+    var value = cached_values[i];
+    var funcId = value["funcId"];
+    var args = value["args"];
+    funcAPIs[funcId].apply(indexObj, args);
+  }
+  cached_values = undefined;
+}
+
+function write_cache(funcId, args) {
+  if (cached_values == undefined) {
+    cached_values = [];
+  }
+  cached_values.push({
+    funcId: funcId,
+    args: [args],
+  });
+}
+function efix_show(elementId) {
+  var currentPage = router.currentPage;
+  var indexObj = currentPage.$indexObj;
+  indexObj.$show(elementId);
+  indexObj.$foreground(elementId);
+}
+function buttonGetKey(elementId) {
+  var currentPage = router.currentPage;
+  var indexObj = currentPage.$indexObj;
+  var element = indexObj.$getElementById(elementId);
+  var res = 0;
+  if (element) {
+    res = element.attributes.KeySet;
+  }
+  return res;
+}
+function buttonSetKey(elementId, value) {
+  var currentPage = router.currentPage;
+  var indexObj = currentPage.$indexObj;
+  var element = indexObj.$getElementById(elementId);
+  if (element) {
+    element.attributes.KeySet = value;
+  }
+}
+
+function systemGetRunState() {
+  return 1;
+}
+function qrcodeSetSrc(id, src) {
+  var currentPage = router.currentPage;
+  var indexObj = currentPage.$indexObj;
+  var obj = indexObj.$getElementPtrById(id);
+  if (obj == undefined) return;
+  var lvgl = require("@native.lvgl7");
+  lvgl.lv_qrcode_set_value(obj, src);
+
+  var element = indexObj.$getElementById(id);
+  element.attributes.value = src;
+}
+function qrcodeGetSrc(id, src) {
+  var currentPage = router.currentPage;
+  var indexObj = currentPage.$indexObj;
+  var element = indexObj.$getElementById(id);
+  if (element == undefined) return;
+  var res = element.attributes.value;
+  return res;
+}
+
+function start_test(args){
+  console.log('==='+args )
+}
+
+function reboot_device(rebootnum){
+  if (rebootnum=="1"){
+    console.log('==='+rebootnum )
+    rebootdevice.reboot()
+  }
+}
+function handleCallback(indexObj, funcId, args) {
+  if (funcId != 21 && funcId != 27) {
+    args[0] = indexObj.$uri + "_" + args[0];
+  }
+  console.log("{ Get } funcId=" + funcId + " args=" + args);
+  // console.log(typeof args);
+  if (indexObj == undefined) {
+    console.log("ERROR!indexObj is undefined..");
+    return;
+  }
+  if (funcAPIs == undefined) {
+    funcAPIs = [
+      indexObj.$getX, //0: 获取x坐标
+      indexObj.$setX, //1: 设置x坐标
+      indexObj.$getY, //2: 获取y坐标
+      indexObj.$setY, //3: 设置y坐标
+      indexObj.$getWidth, //4:获取宽度
+      indexObj.$setWidth, //5:设置宽度
+      indexObj.$getHeight, //6:获取高度
+      indexObj.$setHeight, //7:设置高度
+      indexObj.$setPos, //8:设置x,y
+      indexObj.$setSize, //9:设置宽高
+      indexObj.$setOpacity, //10: 设置透明度
+      indexObj.$setBackgroundColor, //11:设置背景颜色
+      indexObj.$setText, //12:设置文本
+      indexObj.$getText, //13:获取文本
+      indexObj.$setTextColor, //14:设置文本颜色
+      indexObj.$setTextOpacity, //15:获取文本颜色
+      indexObj.$setTextFontSize, //16:设置文本字体大小
+      indexObj.$setImageAngle, //17:设置图片旋转角度
+      indexObj.$setImageZoom, //18:设置图片缩放
+      indexObj.$setSliderValue, //19:设置滑动条位置
+      indexObj.$getSliderValue, //20:获取滑动条位置
+
+      push_page, //21:跳转页面
+      // push_page_and_refresh_caches, //22,跳转页面并立即刷新缓存
+      // write_cache, //23,写缓存
+      // indexObj.$show, //24:显示
+      efix_show, //22:显示
+      indexObj.$hide, //23:隐藏
+      indexObj.$imageRender, //24:设置图片控件图片源
+      buttonGetKey, //25:获取按钮键值
+      buttonSetKey, //26:设置按钮键值
+      systemGetRunState, //27:系统功能 查询运行状态
+      qrcodeGetSrc, //28 获取二维码内容
+      qrcodeSetSrc, //29 设置二维码内容
+      start_test,//30  开始
+      reboot_device,//31 重启
+    ];
+  }
+  console.log("{ Server } funcName=" + funcAPIs[funcId]);
+  var res = funcAPIs[funcId].apply(indexObj, args);
+  console.log("{ Server } funcRes=" + res);
+
+  //这里处理回复数据
+  var resArr = wwProto.response(res, funcId);
+  var resU8Arr = new Uint8Array(resArr);
+  var resBinArr = Buffer.from(resU8Arr);
+
+  console.log("{ Resp } binBuffer");
+  resBinArr.print();
+  uartWW.write(resBinArr);
+  resBinArr.free();
+  console.log("{ Get } End.");
+}
+function reportData(res, funcId) {
+  var resArr = wwProto.response(res, funcId);
+  var resU8Arr = new Uint8Array(resArr);
+  var resBinArr = Buffer.from(resU8Arr);
+
+  uartWW.write(resBinArr);
+  resBinArr.free();
+}
+//inline
+
+//读取配置文件函数
+function loading(filePath) {
+  console.log("loading");
+  if (checkFile(filePath)) {
+    return loadDataByJson(filePath);
+  }
+  return undefined;
+}
+function checkFile(name) {
+  console.log("checkFile " + name);
+  if (NodeJs) {
+    var fs = require("fs");
+    if (fs.existsSync(name)) {
+      return 1;
+    } else {
+      return 0;
+    }
+  } else {
+    //使用系统file操作
+    var fs = require("@system.fs");
+    //检测文件是否存在
+    if (fs.exists(name)) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+}
+function loadDataByJson(name) {
+  console.log("loadDataByJson " + name);
+  if (NodeJs) {
+    var fs = require("fs");
+    var fdata = fs.readFileSync(name, "utf-8");
+    var ret = JSON.parse(fdata);
+  } else {
+    //使用系统file操作
+    var fs = require("@system.fs");
+    var fdata = fs.readFile(name);
+    var ret = JSON.parse(fdata);
+  }
+  return ret;
+}
+
+//extern
+function touchClick(node) {
+  var type = node.attributes.widgetType;
+  console.log("==touchClick:type=" + type);
+  // touchElementClickCallback[type](node);
+  node.attributes.KeySet = node.attributes.KeyCode;
+}
+function refreshPageMessage() {}
+
+function start_senddata(){
+  var resArr = wwProto.response(undefined, 30);
+  var resU8Arr = new Uint8Array(resArr);
+  var resBinArr = Buffer.from(resU8Arr);
+
+  console.log("{ Resp } binBuffer");
+  resBinArr.print();
+  uartWW.write(resBinArr);
+  resBinArr.free();
+  console.log("{ Get } End.");
+  console.log("***************************")
+}
+
+var  setTimeoutdata=setTimeout(function () {
+  start_senddata();
+  clearTimeout(setTimeoutdata);
+}, 500);
+module.exports = {
+  setup: setup,
+  touchClick: touchClick,
+  refreshPageMessage: refreshPageMessage,
+  reportData: reportData,
+};
diff --git a/release/ww/ww_server.q.min.js.bc b/release/ww/ww_server.q.min.js.bc
new file mode 100644
index 0000000000000000000000000000000000000000..8293e5415e76b19cd80187e4e72a8e9c9662ce9a
Binary files /dev/null and b/release/ww/ww_server.q.min.js.bc differ