diff --git a/global/main.js b/global/main.js index 2e3aedfdd516be17baafcedd2a3a599f28f83561..478e1efa435be03ab54931cce069168dbbfa00dd 100644 --- a/global/main.js +++ b/global/main.js @@ -1,5 +1,5 @@ // global value -var g_version = "v1.0.17"; +var g_version = "v1.0.18"; $("[name='lb_version']").html("2020 © LECPServer By Leanboard Tech Ltd  |  " + g_version + "  "); JsProxyAPI.setTitle("LECPServer " + g_version) JsProxyAPI.setNotifyIcon("logo.ico"); @@ -474,6 +474,28 @@ function init_webapi_server() { } else { return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err " + done[1], "rtval": null }); } + } else if (type == "Byte") { + if(protocol=="modbus"){ + let addr = plc_read_node(node, g_plc_data, "addr"); + addr = addr.toLowerCase(); + if(addr.startsWith("holding") || addr.startsWith("h")){ + addr = addr.replace("holding", ""); + addr = addr.replace("h", ""); + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], addr, j['value']); + }else if(addr.startsWith("input") || addr.startsWith("i")){ + return JSON.stringify({ "errcode": 4058, "errmsg": "modbus does not support input register writing", "rtval": null }); + }else{ + addr = addr; + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], addr, j['value']); + } + }else{ + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], plc_read_node(node, g_plc_data, "addr"), j['value']); + } + if (done[0] == true) { + return JSON.stringify({ "errcode": 0, "errmsg": "" }); + } else { + return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err " + done[1], "rtval": null }); + } } else if (type == "Word") { if(protocol=="modbus"){ let addr = plc_read_node(node, g_plc_data, "addr"); @@ -496,7 +518,6 @@ function init_webapi_server() { } else { return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err " + done[1], "rtval": null }); } - } else if (type == "DWord") { if(protocol=="modbus"){ let addr = plc_read_node(node, g_plc_data, "addr"); @@ -565,7 +586,7 @@ function init_webapi_server() { return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err " + done[1], "rtval": null }); } } else { - return JSON.stringify({ "errcode": 4007, "errmsg": "Key type is not in Word / DWord /Bool / String / Float / Double" }); + return JSON.stringify({ "errcode": 4007, "errmsg": "Key type is not in Byte / Word / DWord /Bool / String / Float / Double" }); } } catch (e) { return JSON.stringify({ "errcode": 4056, "errmsg": "plc_write_node err:" + e, "rtval": null }); @@ -673,6 +694,28 @@ function init_webapi_server() { } else { return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err [" + node + "] [" + v + "]" + done[1], "rtval": null }); } + } else if (type == "Byte") { + if(protocol=="modbus"){ + let addr = plc_read_node(node, g_plc_data, "addr"); + addr = addr.toLowerCase(); + if(addr.startsWith("holding") || addr.startsWith("h")){ + addr = addr.replace("holding", ""); + addr = addr.replace("h", ""); + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], addr, v); + }else if(addr.startsWith("input") || addr.startsWith("i")){ + return JSON.stringify({ "errcode": 4058, "errmsg": "modbus does not support input register writing", "rtval": null }); + }else{ + addr = addr; + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], addr, v); + } + }else{ + done = JsProxyAPI.plcWriteBlocking(g_handler_plc[dev], plc_read_node(node, g_plc_data, "addr"), v); + } + if (done[0] == true) { + // return JSON.stringify({ "errcode": 0, "errmsg": "" }); + } else { + return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err [" + node + "] [" + v + "]" + done[1], "rtval": null }); + } } else if (type == "Word") { if(protocol=="modbus"){ let addr = plc_read_node(node, g_plc_data, "addr"); @@ -762,7 +805,7 @@ function init_webapi_server() { return JSON.stringify({ "errcode": 4057, "errmsg": "plc_write_node err [" + node + "] [" + v + "]" + done[1], "rtval": null }); } } else { - return JSON.stringify({ "errcode": 4007, "errmsg": "Key type is not in Word / DWord /Bool / String / Float / Double" }); + return JSON.stringify({ "errcode": 4007, "errmsg": "Key type is not in Byte / Word / DWord /Bool / String / Float / Double" }); } } catch (e) { return JSON.stringify({ "errcode": 4056, "errmsg": "plc_write_node err [" + node + "] " + e, "rtval": null }); @@ -945,6 +988,32 @@ async function init_plc() { } +// 读取PLC信息 Byte +function plc_read_await(handler, addr, length) { + return new Promise((resolve, reject) => { + JsProxyAPI.plcRead(handler, addr, length, function (success, value) { + if (success) { + resolve(value); + } else { + reject(value); + } + }); + }); +} + +// 写入PLC信息 Byte +function plc_write_await(handler, addr, data) { + return new Promise((resolve, reject) => { + JsProxyAPI.plcWrite(handler, addr, data, function (success, value) { + if (success) { + resolve(value); + } else { + reject(value); + } + }); + }); +} + // 读取PLC信息 WORD function plc_read_uint16_await(handler, addr, length) { return new Promise((resolve, reject) => { @@ -1171,6 +1240,9 @@ async function sync_plc_nodes_await() { } else if (g_plc_data['NODES'][dev][key]['type'] == "Bool") { let c = parseInt(g_plc_data['NODES'][dev][key]['length']); g_plc_data['NODES'][dev][key]['value'] = new Array(c).fill(false); + } else if (g_plc_data['NODES'][dev][key]['type'] == "Byte") { + let c = parseInt(g_plc_data['NODES'][dev][key]['length']); + g_plc_data['NODES'][dev][key]['value'] = new Array(c).fill(0); } else if (g_plc_data['NODES'][dev][key]['type'] == "Word") { let c = parseInt(g_plc_data['NODES'][dev][key]['length']); g_plc_data['NODES'][dev][key]['value'] = new Array(c).fill(0); @@ -1252,6 +1324,32 @@ async function sync_plc_nodes_await() { // 其他类型的PLC读取Bool rt = await plc_read_bool_await(g_handler_plc[dev], g_plc_data['NODES'][dev][key]['addr'], parseInt(g_plc_data['NODES'][dev][key]['length'])); } + + + } else if (g_plc_data['NODES'][dev][key]['type'] == "Byte") { + if (protocol == "modbus") { + // modbus类型的PLC读取Byte + // modbus Byte 类型的地址结构有三种 holdingN inputN N + // 如 001 holding001 input001 分别代表 保持寄存器001 保持寄存器001 和输入寄存器001 + // 默认使用保持寄存器 + addr = addr_src.toLowerCase(); + if(addr.startsWith("holding") || addr.startsWith("h")){ + addr = addr.replace("holding", ""); + addr = addr.replace("h", ""); + rt = await plc_read_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])/2); + }else if(addr.startsWith("input") || addr.startsWith("i")){ + addr = addr.replace("input", ""); + addr = addr.replace("i", ""); + rt = await plc_read_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])/2); + }else{ + addr = addr; + rt = await plc_read_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])/2); + } + } else { + // 其他类型的PLC读取Byte + rt = await plc_read_await(g_handler_plc[dev], g_plc_data['NODES'][dev][key]['addr'], parseInt(g_plc_data['NODES'][dev][key]['length'])/2); + } + } else if (g_plc_data['NODES'][dev][key]['type'] == "Word") { if (protocol == "modbus") { // modbus类型的PLC读取Word diff --git a/modules/dashboard.js b/modules/dashboard.js index a55888bf1987ea69fc2ce2de18221569ebb72893..d11c5f4d44c4fc48d40d5c2540e75238b62c2ea4 100644 --- a/modules/dashboard.js +++ b/modules/dashboard.js @@ -1,8 +1,9 @@ var plc_dev_apg_select = ""; var apg_dashboard = null; +var apg_last_val_of_length = ""; -function init_apg_dashboard(){ +function init_apg_dashboard() { apg_dashboard = new AppendGrid({ element: "dt_process_start_page_start_page", uiFramework: "default", @@ -28,6 +29,7 @@ function init_apg_dashboard(){ ctrlOptions: { "": "", "Bool": "Bool", + "Byte": "Byte", "Word": "Word", "DWord": "DWord", "String": "String", @@ -46,7 +48,7 @@ function init_apg_dashboard(){ // e.target.style.backgroundColor = null; } }, - + } }, { @@ -57,7 +59,32 @@ function init_apg_dashboard(){ min: 0, max: 99999999 }, - cellClass: "form-control-input-sm" + cellClass: "form-control-input-sm", + // Add change event + events: { + click: function (e) { + let rowIndex = apg_dashboard.getRowIndex(parseInt(e.uniqueIndex)); + let type = apg_dashboard.getCtrlValue("type", rowIndex); + apg_last_val_of_length = e.target.value; + }, + change: function (e) { + let rowIndex = apg_dashboard.getRowIndex(parseInt(e.uniqueIndex)); + let type = apg_dashboard.getCtrlValue("type", rowIndex); + // 针对Byte类型,需要偶数 + if (type === "Byte") { + if (parseInt(e.target.value) % 2 !== 0) { + // not odd + if(parseInt(apg_last_val_of_length) > parseInt(e.target.value)){ + // -- + e.target.value = parseInt(e.target.value) - 1; + }else{ + // ++ + e.target.value = parseInt(e.target.value) + 1; + } + } + } + } + } }, { name: "note", @@ -90,7 +117,7 @@ function init_apg_dashboard(){ let inputGroup = document.createElement("div"); inputGroup.classList.add("input-group"); parent.appendChild(inputGroup); - + // Create the input elementt let inputControl = document.createElement("button"); let copyControl = document.createElement("button"); @@ -100,7 +127,7 @@ function init_apg_dashboard(){ inputControl.setAttribute("data-tags", uniqueIndex); inputControl.appendChild(t_send); inputGroup.appendChild(inputControl); - + copyControl.name = "btn_dashboard_page_row_copy"; copyControl.setAttribute("data-tags", uniqueIndex); copyControl.appendChild(t_copy); @@ -199,8 +226,10 @@ $("#dt_process_start_page_start_page").on("click", "button[name='btn_dashboard_p if (type != "String") { let a = rsp.split(","); let max = length; - if (a.length < length) { - max = a.length + if (type != "Byte") { + if (a.length < length) { + max = a.length + } } for (i = 0; i < max; i++) { buff.push(a[i]); @@ -502,7 +531,7 @@ $("[name='btn_dashboard_page_delete_device']").on("click", function () { let last_device_select = plc_dev_apg_select; JsProxyAPI.fileWrite("plc.conf", JSON.stringify(g_plc_data, null, "\t")); - + init_device_list(); // 重新加载所有设备 plc_close_all();