// global value var g_version = "v1.0.23"; $("[name='lb_version']").html("2020 © LECPServer By Leanboard Tech Ltd  |  " + g_version + "  "); JsProxyAPI.setTitle("LECPServer " + g_version) JsProxyAPI.setNotifyIcon("logo.ico"); JsProxyAPI.setNotifyTitle("LECPServer"); var g_plc_data = null; // plc当前数据 var g_user_login = ""; // 当前登陆用户 var g_handler_plc = {}; var g_handler_db = null; var g_modules_conf = null; var g_settings_conf = null; var g_sync_worker_lock = null; // PLC的返回状态,包括入口和出口,可以分别进行报警和显示 // Online和Offline只看入口即可 var g_plc_status = {} // 读取 settings.conf 配置信息 function load_settings_conf() { let s = JsProxyAPI.fileRead("./settings.conf"); if (s == "") { alert("settings.conf " + i18next.t('main.does_not_exist')); return false; } try { g_settings_conf = JSON.parse(s); return true; } catch (e) { alert(i18next.t('main.incorrect_format_of_file') + " settings.conf:" + e); return false; } } // 读取 modules.conf 配置信息 function load_modules_conf() { let s = JsProxyAPI.fileRead("./modules.conf"); if (s == "") { alert("modules.conf " + i18next.t('main.does_not_exist')); return false; } try { g_modules_conf = JSON.parse(s); return true; } catch (e) { alert(i18next.t('main.incorrect_format_of_file') + " modules.conf:" + e); return false; } } // 读取 plc.conf 配置信息 function load_plc_conf() { let s = JsProxyAPI.fileRead("./plc.conf"); if (s == "") { alert("plc.conf " + i18next.t('main.does_not_exist')); g_plc_data = { "NODES": {}, "DEVS": {}, "WEBAPI": { "PORT": 8088 } } JsProxyAPI.fileWrite("plc.conf", JSON.stringify(g_plc_data, null, "\t")); return false; } try { g_plc_data = JSON.parse(s); return true; } catch (e) { alert(i18next.t('main.incorrect_format_of_file') + " plc.conf:" + e); return false; } } function deepCopy(target) { let copyed_objs = [];//此数组解决了循环引用和相同引用的问题,它存放已经递归到的目标对象 function _deepCopy(target) { if ((typeof target !== 'object') || !target) { return target; } for (let i = 0; i < copyed_objs.length; i++) { if (copyed_objs[i].target === target) { return copyed_objs[i].copyTarget; } } let obj = {}; if (Array.isArray(target)) { obj = [];//处理target是数组的情况 } copyed_objs.push({ target: target, copyTarget: obj }) Object.keys(target).forEach(key => { if (obj[key]) { return; } obj[key] = _deepCopy(target[key]); }); return obj; } return _deepCopy(target); } // 队列对象 function Queue() { var items = []; this.enqueue = function (element) { items.push(element); }; this.dequeue = function () { return items.shift(); }; this.front = function () { return items[0]; }; this.end = function () { return items[items.length - 1]; }; this.clear = function () { items = []; }; this.isEmpty = function () { return items.length == 0; }; this.size = function () { return items.length; }; this.print = function () { console.log(items.toString()); }; this.toJson = function () { // JSON.stringify(g_tray_data_entry, null, "\t") return JSON.stringify(items, null, "\t"); }; this.load = function (t) { items = JSON.parse(t); } this.getItems = function () { return items; } } function get_guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); }); } // ======================================================================= // ======================================================================= // ===================== 全局函数们 ===================================== // ======================================================================= // ======================================================================= // 延时函数 function sleep(time) { return new Promise((resolve) => setTimeout(resolve, time)); } function get_datatime_by_hhmmss() { let d = new Date(); return d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds(); } // WORD ARRAY 到 BOOLEAN ARRAY的转换 function word_array_to_boolean_array(values) { let d = []; for (i in values) { let v = values[i]; let b = v.toString(2); b = ('000000000000000000' + b).slice(-16).split(""); let p = 0; a = []; for (i = b.length - 1; i >= 0; i--) { a[p] = b[i]; p++; } d = d.concat(a); } return d; } // BOOLEAN ARRAY 到 WORD ARRAY 的转换 function boolean_array_to_word_array(values) { // 先确认这个word占用多少个,取最大的idx let wl = values.length / 16 // 如果是boolean的值,则先转为int数组 if (typeof (values[values.length - 1]) == "boolean") { for (i = 0; i < values.length; i++) { if (values[i] == true) values[i] = 1; if (values[i] == false) values[i] = 0; } } let d = []; for (i = 0; i < wl; i++) { let s = ""; for (c = 16 - 1; c >= 0; c--) { s += values[i * 16 + c].toString(); } d[i] = parseIntInt(s, 2); } return d; } // WORD ARRAY 到 STRING ARRAY的转换 function word_array_to_string_array(values) { let ds = [] for (i in values) { let ws = values[i]; let d = []; for (c in values[i]) { let w = values[i][c]; let hexs = w.toString(16); // 将每个word转为两个byte hexs = ('0000' + hexs).slice(-4); //取高低位 let h = hexs.substring(0, 2); let l = hexs.substring(2, 4); // 放入数组内 d = d.concat([l, h]); } let s = ""; for (let k = 0; k < d.length; k++) { s += String.fromCharCode(parseInt(d[k], 16)); } // 转为字符串 ds[i] = s.replace(/\0/g, ''); } return ds; } // STRING ARRAY 到 WORD ARRAY 的转换 length_of_words 参数是WORD的长度 // 譬如["AAA","BBB"] 转为 WORD ARRAY // string_array_to_word_array(["AAA","BBB"], 16) // 返回 // [ // [16705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // [16962, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // ] // 然后可以用该值作为二维数组发送到OPCUA function string_array_to_word_array(values, length_of_words) { let ds = [] for (i in values) { let s = values[i]; // 字符串拆分成byte let ss = s.split(""); let p = 0; let d = []; for (c = 0; c < length_of_words; c++) { if (ss[p] == null && ss[p + 1] == null) { d.push(0); } else if (ss[p] != null && ss[p + 1] == null) { let h = ss[p].charCodeAt(0); d.push(h * 256); p += 2; } else { let h = ss[p + 1].charCodeAt(0); let l = ss[p].charCodeAt(0); p += 2; d.push(h * 256 + l); } } ds.push(d) } return ds; } // 插入dashboard日志记录 // entry select pick_01 pick_02 exits function insert_dashboard_data(msg, type = "default", zone = "entry") { // label-success 完成一组工作 label-default 中间信息 label-danger 报警信息 let t = "label-" + type; let html = '
  • ' + '
    ' + msg + '
    ' + '
    ' + get_datatime_by_hhmmss() + '
  • '; $("[name='msg_dashboard_page_" + zone + "']").prepend(html); if ($("[name='msg_dashboard_page_" + zone + "']").children('li').length > 500) { // 删掉后面一个元素 $("[name='msg_dashboard_page_" + zone + "']").children('li:last-child').remove(); } } // ======================================================================= // ======================================================================= // ===================== 主要通讯函数 ==================================== // ======================================================================= // ======================================================================= // 初始化 WebAPI 服务器 function init_webapi_server() { // 获取点位的值 function plc_read_node(key, plc_data, ch_node = "value") { // 查询key是否存在 try { element = plc_data; // 递推每个节点名称 (key + "." + ch_node).split(".").forEach(function (x) { // 获取节点数据 element = element[x]; }); // 如果拿不到东西 if (typeof (element) == "undefined") return null; return element; } catch (e) { return null; } } function plc_get_node_dev(key, plc_data) { // 查询key是否存在 let dev = ""; try { element = plc_data; // 递推每个节点名称 (key).split(".").forEach(function (x) { // 获取节点数据 if (dev == "" && x !== "NODES") dev = x; element = element[x]; }); // 如果拿不到东西 if (typeof (element) == "undefined") return null; return dev; } catch (e) { return null; } } let r = JsProxyAPI.webAPIStart(g_plc_data['WEBAPI']['PORT'], function (success, handler) { console.log(success, handler); }, function (msg) { console.log(msg); // 将msg转为json结构 let j = null; try { j = JSON.parse(msg); } catch (e) { return JSON.stringify({ "errcode": 4001, "errmsg": "JSON parsing error" }); } // 判断 action 是否存在 // action 的名称有 plc_read_node / plc_write_node / plc_read_nodes / plc_write_nodes if (!j.hasOwnProperty("action")) { return JSON.stringify({ "errcode": 4002, "errmsg": "Key action is not exist" }); } if (j['action'] != "plc_read_node" && j['action'] != "plc_write_node" && j['action'] != "plc_read_nodes" && j['action'] != "plc_write_nodes") { return JSON.stringify({ "errcode": 4003, "errmsg": "Key action is not in plc_read_node / plc_write_node / plc_read_nodes / plc_write_nodes" }); } if (!j.hasOwnProperty("node")) { return JSON.stringify({ "errcode": 4002, "errmsg": "Key node is not exist" }); } // 如果PLC离线则返回异常 if (j['action'] == "plc_read_node") { } if (j['action'] == "plc_read_nodes") { } // 处理 plc_read_node if (j['action'] == "plc_read_node") { console.time("A"); let dev = plc_get_node_dev(j['node'], g_plc_data); if (dev == null || typeof (g_plc_status[dev]) == "undefined") { return JSON.stringify({ "errcode": 4012, "errmsg": "Device " + dev + " is not exist" }); } if (g_plc_status[dev]['online'] == false) { return JSON.stringify({ "errcode": 4013, "errmsg": "Device " + dev + " is offline" }); } dev = null; let rt = plc_read_node(j['node'], g_plc_data); if (rt == null) { return JSON.stringify({ "errcode": 4055, "errmsg": "Node is not correct", "rtval": null }); } console.timeEnd("A"); return JSON.stringify({ "errcode": 0, "errmsg": "", "rtval": rt }); } // 处理 plc_read_nodes if (j['action'] == "plc_read_nodes") { // j['node'] = [node1, node2, node3, node4, node5 ... ] // 判断有无节点参数 if (!j.hasOwnProperty("node")) { return JSON.stringify({ "errcode": 4007, "errmsg": "Key node is not exist" }); } if (!Array.isArray(j['node'])) { return JSON.stringify({ "errcode": 4009, "errmsg": "Key node is not array" }); } let rts = []; for (let i in j['node']) rts.push(null); for (let i in j['node']) { let node = j['node'][i]; // 如果PLC离线则返回异常 let dev; for (let n in j['node']) { dev = plc_get_node_dev(node, g_plc_data); break; } if (dev == null || typeof (g_plc_status[dev]) == "undefined") { return JSON.stringify({ "errcode": 4012, "errmsg": "Device " + dev + " is not exist" }); } if (g_plc_status[dev]['online'] == false) { return JSON.stringify({ "errcode": 4013, "errmsg": "Device " + dev + " is offline" }); } dev = null; let rt = plc_read_node(node, g_plc_data); if (rt == null) { rts[i] = null; return JSON.stringify({ "errcode": 4055, "errmsg": "Node [" + node + "] is not exists", "rtval": rts }); } rts[i] = rt; } return JSON.stringify({ "errcode": 0, "errmsg": "", "rtval": rts }); } // 处理 plc_write_node if (j['action'] == "plc_write_node") { /* // 先判断有没有 type 这个关键字 if(!j.hasOwnProperty("type")){ return JSON.stringify({"errcode":4006, "errmsg":"Key type is not exist"}); } */ // 判断有无值参数 if (!j.hasOwnProperty("value")) { return JSON.stringify({ "errcode": 4007, "errmsg": "Key value is not exist" }); } // 判断有无节点参数 if (!j.hasOwnProperty("node")) { return JSON.stringify({ "errcode": 4007, "errmsg": "Key node is not exist" }); } let node = j['node']; let type = plc_read_node(node, g_plc_data, "type"); let dev = plc_get_node_dev(node, g_plc_data); let done = 0; // 如果是模拟驱动模式,直接写入本buffer值 if (g_plc_data['DEVS'][dev]['PLC_DRIVER'] == "simulation") { let rt = plc_read_node(node, g_plc_data, "addr"); if (rt == null) { return JSON.stringify({ "errcode": 4057, "errmsg": "Node [" + node + "] is not exists", "rtval": rt }); } let a = node.split("."); g_plc_data['NODES'][dev][a[a.length - 1]]['value'] = j['value']; return JSON.stringify({ "errcode": 0, "errmsg": "" }); } if (type == null || dev == null) { return JSON.stringify({ "errcode": 4059, "errmsg": "Node [" + node + "] is not exists", "rtval": null }); } let protocol = ""; if (g_modules_conf[g_plc_data['DEVS'][dev]['PLC_DRIVER']]['TYPE'].startsWith("MODBUS")) { protocol = "modbus"; } try { let done = false; let rtval = null; if (type == "String") { 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.plcWriteStringBlocking(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.plcWriteStringBlocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteStringBlocking(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 == "Bool") { if (protocol == "modbus") { let addr = plc_read_node(node, g_plc_data, "addr"); addr = addr.toLowerCase(); if (addr.startsWith("coil") || addr.startsWith("c")) { addr = addr.replace("coil", ""); addr = addr.replace("c", ""); done = JsProxyAPI.plcWriteBoolBlocking(g_handler_plc[dev], addr, j['value']); } else if (addr.startsWith("discrete") || addr.startsWith("d")) { return JSON.stringify({ "errcode": 4058, "errmsg": "modbus does not support discrete register writing", "rtval": null }); } else { addr = addr; done = JsProxyAPI.plcWriteBoolBlocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteBoolBlocking(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 == "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"); addr = addr.toLowerCase(); if (addr.startsWith("holding") || addr.startsWith("h")) { addr = addr.replace("holding", ""); addr = addr.replace("h", ""); done = JsProxyAPI.plcWriteUInt16Blocking(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.plcWriteUInt16Blocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteUInt16Blocking(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 == "DWord") { 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.plcWriteUInt32Blocking(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.plcWriteUInt32Blocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteUInt32Blocking(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 == "Float") { 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.plcWriteFloatBlocking(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.plcWriteFloatBlocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteFloatBlocking(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 == "Double") { 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.plcWriteDoubleBlocking(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.plcWriteDoubleBlocking(g_handler_plc[dev], addr, j['value']); } } else { done = JsProxyAPI.plcWriteDoubleBlocking(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 { 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 }); } /* if(rt==false){ return JSON.stringify({"errcode":4057, "errmsg":"plc_write_node err", "rtval":null}); } return JSON.stringify({"errcode":0, "errmsg":"", "rtval":rt}); */ } if (j['action'] == "plc_write_nodes") { // 判断有无值参数 if (!j.hasOwnProperty("value")) { return JSON.stringify({ "errcode": 4007, "errmsg": "Key value is not exist" }); } // 判断有无节点参数 if (!j.hasOwnProperty("node")) { return JSON.stringify({ "errcode": 4007, "errmsg": "Key node is not exist" }); } //判断节点和值参数是否是数组 if (!Array.isArray(j['value'])) { return JSON.stringify({ "errcode": 4009, "errmsg": "Key value is not array" }); } if (!Array.isArray(j['node'])) { return JSON.stringify({ "errcode": 4009, "errmsg": "Key node is not array" }); } let nodes = j['node']; let i = 0; for (i in nodes) { let node = nodes[i]; let type = plc_read_node(node, g_plc_data, "type"); let dev = plc_get_node_dev(node, g_plc_data); let done = 0; // 如果是模拟驱动模式,直接写入本buffer值 if (g_plc_data['DEVS'][dev]['PLC_DRIVER'] == "simulation") { let rt = plc_read_node(node, g_plc_data, "addr"); if (rt == null) { return JSON.stringify({ "errcode": 4057, "errmsg": "Node [" + node + "] is not exists", "rtval": rt }); } let a = node.split("."); g_plc_data['NODES'][dev][a[a.length - 1]]['value'] = j['value'][i]; return JSON.stringify({ "errcode": 0, "errmsg": "" }); } if (type == null || dev == null) { return JSON.stringify({ "errcode": 4059, "errmsg": "Node [" + node + "] is not exists", "rtval": null }); } let protocol = ""; if (g_modules_conf[g_plc_data['DEVS'][dev]['PLC_DRIVER']]['TYPE'].startsWith("MODBUS")) { protocol = "modbus"; } try { let done = false; let rtval = null; let v = j['value'][i]; if (type == "String") { 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.plcWriteStringBlocking(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.plcWriteStringBlocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteStringBlocking(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 == "Bool") { if (protocol == "modbus") { let addr = plc_read_node(node, g_plc_data, "addr"); addr = addr.toLowerCase(); if (addr.startsWith("coil") || addr.startsWith("c")) { addr = addr.replace("coil", ""); addr = addr.replace("c", ""); done = JsProxyAPI.plcWriteBoolBlocking(g_handler_plc[dev], addr, v); } else if (addr.startsWith("discrete") || addr.startsWith("d")) { return JSON.stringify({ "errcode": 4058, "errmsg": "modbus does not support discrete register writing", "rtval": null }); } else { addr = addr; done = JsProxyAPI.plcWriteBoolBlocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteBoolBlocking(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 == "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"); addr = addr.toLowerCase(); if (addr.startsWith("holding") || addr.startsWith("h")) { addr = addr.replace("holding", ""); addr = addr.replace("h", ""); done = JsProxyAPI.plcWriteUInt16Blocking(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.plcWriteUInt16Blocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteUInt16Blocking(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 == "DWord") { 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.plcWriteUInt32Blocking(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.plcWriteUInt32Blocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteUInt32Blocking(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 == "Float") { 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.plcWriteFloatBlocking(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.plcWriteFloatBlocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteFloatBlocking(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 == "Double") { 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.plcWriteDoubleBlocking(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.plcWriteDoubleBlocking(g_handler_plc[dev], addr, v); } } else { done = JsProxyAPI.plcWriteDoubleBlocking(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 { 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 }); } i++; } return JSON.stringify({ "errcode": 0, "errmsg": "" }); } return "AAAA"; } ); } // 初始化数据库 async function init_db() { let r = JsProxyAPI.dbConnect("Data Source=./database/sql.db;Pooling=true;FailIfMissing=false", "SQLITE", function (success, handler) { console.log(success, handler); g_handler_db = handler; }); } // 执行sql语句,包括 insert into / delete / update async function excute_non_query(handler, sql) { return new Promise((resolve, reject) => { let r = JsProxyAPI.dbExcuteNonQuery(handler, sql, function (success, dt) { console.log(success, dt); if (success) { resolve(dt); } else { reject(dt); } }); }); } // 执行sql语句,并返回结果,针对select语句 async function excute_query(handler, sql) { return new Promise((resolve, reject) => { let r = JsProxyAPI.dbExcuteQuery(handler, sql, function (success, dt) { console.log(success, dt); if (success) { resolve(dt); } else { reject(dt); } }); }); } // 关闭数据库 function close_db() { if (g_handler_db != null) if (g_handler_db != "") JsProxyAPI.dbClose(g_handler_db); } // 初始化PLC async function init_plc_device(dev) { let d = g_plc_data['DEVS'][dev] if (Object.keys(d).length == 0) return; if (d['PLC_DRIVER'] == "") return; if (d['PLC_DRIVER'] == "simulation") return; return new Promise((resolve, reject) => { // 欧姆龙fins协议 let dd = g_modules_conf[d['PLC_DRIVER']]; let type = dd['TYPE']; let string_reverse = false; if (d['STRING_REVERSE'] === "true") { string_reverse = true; } else { string_reverse = false; } if (type == "TCP" || type == "MODBUSTCP") { let s = dd['FUNCTION'] + ',function(success,handler){console.log(success,handler);if(success){resolve(handler)}else{reject(handler)}},' + Number(d['RECV_TIMEOUT']) + ',"' + d['DATAFORMAT'] + '",' + Boolean(string_reverse) + ',true);'; eval(s); } if (type == "UDP" || type == "MODBUSUDP") { let s = dd['FUNCTION'] + ',function(success,handler){console.log(success,handler);if(success){resolve(handler)}else{reject(handler)}},"' + d['DATAFORMAT'] + '",' + Boolean(string_reverse) + ');'; eval(s); } if (type == "SERIAL" || type == "MODBUSSERIAL") { let s = dd['FUNCTION'] + ',function(success,handler){console.log(success,handler);if(success){resolve(handler)}else{reject(handler)}},"' + d['DATAFORMAT'] + '",' + Boolean(string_reverse) + ');'; eval(s); } }); } // 启动时候先将PLC点位清空 async function init_plc() { for (let dev in g_plc_data['DEVS']) { try { let rt = await init_plc_device(dev); g_handler_plc[dev] = rt; } catch (e) { alert("初始化PLC失败,请重试:" + dev + " -- " + e) } } } // 读取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) => { JsProxyAPI.plcReadUInt16(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 WORD function plc_write_uint16_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteUInt16(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 DWORD function plc_write_uint32_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteUInt32(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 读取PLC信息 DWORD function plc_read_uint32_await(handler, addr, length) { return new Promise((resolve, reject) => { JsProxyAPI.plcReadUInt32(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 读取PLC信息 String function plc_read_string_await(handler, addr, length) { return new Promise((resolve, reject) => { JsProxyAPI.plcReadString(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 STRING function plc_write_string_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteString(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 读取PLC信息 Bool function plc_read_bool_await(handler, addr, length) { return new Promise((resolve, reject) => { JsProxyAPI.plcReadBool(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 Bool function plc_write_bool_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteBool(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 读取PLC信息 Float function plc_read_float_await(handler, addr, length) { return new Promise((resolve, reject) => { JsProxyAPI.plcReadFloat(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 Float function plc_write_float_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteFloat(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 读取PLC信息 Double function plc_read_double_await(handler, addr, length) { return new Promise((resolve, reject) => { JsProxyAPI.plcReadDouble(handler, addr, length, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 写入PLC信息 Double function plc_write_double_await(handler, addr, data) { return new Promise((resolve, reject) => { JsProxyAPI.plcWriteDouble(handler, addr, data, function (success, value) { if (success) { resolve(value); } else { reject(value); } }); }); } // 关闭所有plc连接 function plc_close_all() { for (dev in g_handler_plc) { plc_close(g_handler_plc[dev]); delete g_handler_plc[dev]; } } // 关闭PLC连接 function plc_close(handler) { if (handler == "") return; try { JsProxyAPI.plcConnectClose(handler); } catch (e) { console.log(e); } } // Http 通讯 function http_request_await(url, data) { return new Promise((resolve, reject) => { JsProxyAPI.loggerWrite("http_request: [" + url + "] " + JSON.stringify(data).replace(/\\/g, "").replace(/\"/g, "\'"), "COMM", g_user_login); $.ajax({ url: url, data: JSON.stringify(data), contentType: "application/x-www-form-urlencoded", type: 'POST', timeout: 2000, success: function (response) { JsProxyAPI.loggerWrite("http_request response: [" + url + "] " + JSON.stringify(response).replace(/\\/g, "").replace(/\"/g, "\'"), "COMM", g_user_login); resolve(response); }, error: function (x, t, m) { JsProxyAPI.loggerWrite("http_request response Err: [" + url + "] " + JSON.stringify(data).replace(/\\/g, "").replace(/\"/g, "\'") + " ERR" + t, "COMM", g_user_login); if (t === "timeout") { reject(t); } else { reject(t); } } }); }); } // 同步Input Output数据(入口PLC) async function sync_plc_nodes_await(dev) { // 查找全部节点 // console.time("a"); let key = null; // let dev = null; // for (dev in g_plc_data['NODES']) { // } if (dev == "") return; // 如果是模拟驱动的方式,不做点位同步,默认在线 if (g_plc_data['DEVS'][dev]['PLC_DRIVER'] == "simulation") { g_plc_status[dev] = { "online": true, "errcode": 0, "errmsg": "" }; // 如果values没有初始化,那给他初始化的值 try { for (key in g_plc_data['NODES'][dev]) { if (!g_plc_data['NODES'][dev][key].hasOwnProperty("value")) { if (g_plc_data['NODES'][dev][key]['type'] == "String") { g_plc_data['NODES'][dev][key]['value'] = ""; } 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); } else if (g_plc_data['NODES'][dev][key]['type'] == "DWord") { let c = parseInt(g_plc_data['NODES'][dev][key]['length']); g_plc_data['NODES'][dev][key]['value'] = new Array(c).fill(0); } else { let c = parseInt(g_plc_data['NODES'][dev][key]['length']); g_plc_data['NODES'][dev][key]['value'] = new Array(c).fill(0); } } } } catch (e) { g_plc_status[dev]['online'] = false; g_plc_status[dev]['errmsg'] = e.toString(); JsProxyAPI.loggerWrite("sync_plc_nodes simulation : [" + dev + "] " + "[" + key + "] " + e.toString().replace(/[\r\n]/g, "").replace(/\\/g, "\\\\"), "COMM", g_user_login); } return; } // 如果状态量没初始化的,初始化他 if (g_plc_status[dev] == null) { g_plc_status[dev] = { "online": false, "errcode": 0, "errmsg": "" }; } if (Object.keys(g_plc_data['NODES'][dev]).length == 0) { g_plc_status[dev]['online'] = false; return; } let addr_src = ""; let addr = ""; try { for (key in g_plc_data['NODES'][dev]) { let rt = null; let protocol = ""; if (g_modules_conf[g_plc_data['DEVS'][dev]['PLC_DRIVER']]['TYPE'].startsWith("MODBUS")) { protocol = "modbus"; } addr_src = g_plc_data['NODES'][dev][key]['addr']; if (g_plc_data['NODES'][dev][key]['type'] == "String") { if (protocol == "modbus") { // modbus类型的PLC读取String // modbus Word 类型的地址结构有三种 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_string_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("input") || addr.startsWith("i")) { addr = addr.replace("input", ""); addr = addr.replace("i", ""); rt = await plc_read_string_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_string_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的PLC读取String rt = await plc_read_string_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'] == "Bool") { if (protocol == "modbus") { // modbus类型的PLC读取Bool // modbus Bool 类型的地址结构有三种 coilN discreteN N // 如 001 coil001 discrete001 分别代表 线圈的001 线圈001 和离散寄存器001 // 默认使用线圈 addr = addr_src.toLowerCase(); if (addr.startsWith("coil") || addr.startsWith("c")) { addr = addr.replace("coil", ""); addr = addr.replace("c", ""); rt = await plc_read_bool_await(g_handler_plc[dev], "x=1;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("discrete") || addr.startsWith("d")) { addr = addr.replace("discrete", ""); addr = addr.replace("d", ""); rt = await plc_read_bool_await(g_handler_plc[dev], "x=2;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_bool_await(g_handler_plc[dev], "x=1;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的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']) ); } 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']) ); } else { addr = addr; rt = await plc_read_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length']) ); } } 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']) ); } } else if (g_plc_data['NODES'][dev][key]['type'] == "Word") { if (protocol == "modbus") { // modbus类型的PLC读取Word // modbus Word 类型的地址结构有三种 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_uint16_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("input") || addr.startsWith("i")) { addr = addr.replace("input", ""); addr = addr.replace("i", ""); rt = await plc_read_uint16_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_uint16_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的PLC读取Word rt = await plc_read_uint16_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'] == "DWord") { if (protocol == "modbus") { // modbus类型的PLC读取DWord // modbus DWord 类型的地址结构有三种 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_uint32_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("input") || addr.startsWith("i")) { addr = addr.replace("input", ""); addr = addr.replace("i", ""); rt = await plc_read_uint32_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_uint32_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的PLC读取DWord rt = await plc_read_uint32_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'] == "Float") { if (protocol == "modbus") { // modbus类型的PLC读取Float // modbus Word 类型的地址结构有三种 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_float_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("input") || addr.startsWith("i")) { addr = addr.replace("input", ""); addr = addr.replace("i", ""); rt = await plc_read_float_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_float_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的PLC读取Float rt = await plc_read_float_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'] == "Double") { if (protocol == "modbus") { // modbus类型的PLC读取Double // modbus Word 类型的地址结构有三种 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_double_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else if (addr.startsWith("input") || addr.startsWith("i")) { addr = addr.replace("input", ""); addr = addr.replace("i", ""); rt = await plc_read_double_await(g_handler_plc[dev], "x=4;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } else { addr = addr; rt = await plc_read_double_await(g_handler_plc[dev], "x=3;" + addr, parseInt(g_plc_data['NODES'][dev][key]['length'])); } } else { // 其他类型的PLC读取Double rt = await plc_read_double_await(g_handler_plc[dev], g_plc_data['NODES'][dev][key]['addr'], parseInt(g_plc_data['NODES'][dev][key]['length'])); } } g_plc_data['NODES'][dev][key]['value'] = rt; } g_plc_status[dev]['online'] = true; } catch (e) { g_plc_status[dev]['online'] = false; g_plc_status[dev]['errmsg'] = e.toString(); JsProxyAPI.loggerWrite("sync_plc_nodes: [" + dev + "] " + "[" + addr_src + "] " + e.toString().replace(/[\r\n]/g, "").replace(/\\/g, "\\\\"), "COMM", g_user_login); } } // ======================================================================= // ======================================================================= // ===================== 主要逻辑函数 ==================================== // ======================================================================= // ======================================================================= // PLC同步线程逻辑 // 同步入口PLC数据 // 异常状态给到 g_plc_status // 1 读取所有点位,包括PLC的IN和OUT的状态量 /* async function process_loop_plc_data_sync() { while (1) { await sleep(100); // 读取所有的opcua点位状态 await sync_plc_nodes_await(); } } */ async function process_loop_plc_data_sync(dev, guid) { while (1) { await sleep(100); // 读取所有的opcua点位状态 if (g_sync_worker_lock[guid]['running'] == false) break; await sync_plc_nodes_await(dev); } } function load_sync_workers() { let dev; let guid = ""; g_sync_worker_lock = {}; for (dev in g_plc_data['DEVS']) { guid = get_guid(); g_sync_worker_lock[guid] = {}; g_sync_worker_lock[guid]['dev'] = dev; g_sync_worker_lock[guid]['running'] = true; process_loop_plc_data_sync(dev, guid); } } function unload_sync_workers() { let guid for (guid in g_sync_worker_lock) { g_sync_worker_lock[guid]['running'] = false; } } // 加载模块配置 if (!load_modules_conf()) { alert("模块配置文件异常,无法启动程序!"); } else { // 读取settings配置 load_settings_conf(); // 启动系统 load_plc_conf(); // 初始化PLC连接 init_plc(); // 初始化数据库 init_db(); //初始化WebApi服务器 init_webapi_server() if (g_settings_conf != null) { let s = g_settings_conf['DISPLAY_SCREEN']; if (s == 0 || s == 1) { JsProxyAPI.setDesktopBounds(s); } } // JsProxyAPI.setDesktopBounds(0); // process_loop_plc_data_sync(); load_sync_workers(); // let pp = {}; // pp['AAA'] = "KKKKK"; // let f = Function('JsProxyAPI.showMessage(pp["AAA"]);') // eval('JsProxyAPI.showMessage(pp["AAA"]);'); //f(); } //# sourceURL=main.js