Files
controls-web/controls-rework/test/kepware/JS/engine.js
2026-02-17 09:29:34 -06:00

699 lines
25 KiB
JavaScript

//DISCLAIMER HERE//
//Script for the engine
//Not releated for v6 API. These are just the client engines to power the logic and data in the front end
//Back End Functions that loops non-stop
function defaultViewState() {
//Sets up the default configurator views
$("#textJsonEditor").show();
$("#jsonEditorContainer").hide();
$("#tagListContainer").hide();
$("#channelPanel").show();
$("#devicePanel").hide();
$("#tagPanel").hide();
$("#deleteChannel").hide();
$("#deleteDevice").hide();
$("#readProjObj").hide();
$("#useCase1Panel").hide();
$("#iotGatewayPanel").hide();
}
function Loop() {
//Checks if debug is enabled
if ($("#debugState").is(':checked')) {
debugState = true;
$("#readProjObj").show();
$('body').css('background-color', 'yellow');
} else {
debugState = false;
$("#readProjObj").hide();
$('body').css('background-color', '#4CAF50');
}
//Check if State should be connected. If debug is true, we stop the loop and dont do anything.
if (connectState && !debugState) {
if (!disconnected) {
$("#connectedTo").css("color", "green");
$(".hideAfterConnect").hide();
$("#updateConfig").hide();
var htmlString = "<li><Strong>You are now connected as : </Strong>" + userName + "</li>";
$("#connectedUserTxt").html(htmlString);
updateStatsBarServer(inputServer);
updateStatsBarChannelCount();
updateStatsDeviceCount();
readEventLog();
var tempblank = [];
if (eventArrayChanged && (eventArray.toString() != tempblank.toString())) {
var tempindex = 0;
for (var i = 0; i < eventArray.length; i++) {
if (eventArray[i].timestamp == lastKnownTime) {
tempindex = i + 1;
}
}
for (var j = tempindex; j < eventArray.length; j++) {
updateEventLog(eventArray[j].timestamp, eventArray[j].event, eventArray[j].message);
}
lastKnownTime = eventArray[eventArray.length - 1].timestamp;
}
updateProj(inputServer); //For maintaining the latest value
if (treeChanged) {
updateStatsBarServer(inputServer);
updateStatsBarChannelCount();
updateStatsDeviceCount();
treeChanged = false;
drawTree(channelList);
$('#deviceTree').on('select_node.jstree', function(e, data) {
var loMainSelected = data;
getNodeAndParent(loMainSelected);
});
}
$('#deviceTree').on('ready.jstree', function() {
$("#deviceTree").jstree("open_all");
});
//deviceTreeListener();
} else {
$("#connectedTo").css("color", "red");
$(".hideAfterConnect").show();
$("#updateConfig").show();
}
} else {
//When disconnected or in debug mode
$("#connectedTo").css("color", "red");
$(".hideAfterConnect").show();
$("#updateConfig").show();
}
}
//General Functions
function getUserInputs() {
inputServer = document.getElementById('server').value;
inputChannel = document.getElementById('channel').value;
inputChannelType = document.getElementById('channelType').value;
inputDevice = document.getElementById('device').value;
inputDevID = document.getElementById('deviceId').value;
inputTag = document.getElementById('tag').value;
inputTagAddr = document.getElementById('tagAddr').value;
inputTagType = document.getElementById("tagType").value;
inputDriver = document.getElementById('channelType').value;
userName = document.getElementById('userName').value;
userPass = document.getElementById('userPass').value;
var authString = userName + ":" + userPass;
encodeAuth = btoa(authString);
}
function getNodeAndParent(loSelectedNode) {
//Gets the Node clicked
try {
var lnLevel = loSelectedNode.node.parents.length;
var lsSelectedID = loSelectedNode.node.id;
var loParent = $("#" + lsSelectedID);
var selected = loSelectedNode.node.text;
var tempList = [];
var channel;
var device;
var driver;
for (var ln = 0; ln <= lnLevel - 1; ln++) {
loParent = loParent.parent().parent();
if (loParent.children()[1] !== undefined) {
tempList.push(loParent.children()[1].text);
}
}
if (tempList.length === 0) {
//This is a channel
channel = selected;
cselected = selected;
console.log("cselected is" + cselected);
for (var i = 0; i < channelList.length; i++) {
if (channel == channelList[i].text) {
driver = channelList[i].driver;
console.log(driver);
}
}
//console.log("channel is " + channel + ", driver is " + driver);
channelSelected(channel, driver);
} else {
//This is a device
channel = tempList[0];
cselected = channel;
document.getElementById("channel").value = cselected;
driver = tempList[0].driver;
document.getElementById("channelType").value = driver;
device = selected;
dselected = selected;
document.getElementById("device").value = dselected;
console.log("cselected is" + cselected);
console.log("dselected is" + dselected);
deviceSelected(device, channel);
console.log("Getting Tags for " + device + " under " + channel);
getTags(device, channel);
}
} catch (err) {
updateLog('Error in fetching selection in tree');
}
}
//Dropdown display functions
/* When the user clicks on the button, toggle between hiding and showing the dropdown content */
function dropdown() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.inputButton')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (var i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
//Device List Functions
function drawTree(treeObj) {
//console.log("Drawing Tree");
//console.log("Input is " + treeObj);
//Draws the Device list based on the jSON object parsed into it
//Has to destroy the tree and create a new one. There are no update function
$('#deviceTree').jstree("destroy").empty();
$('#deviceTree').jstree({
'core': {
'check_callback': true,
'data': channelList
}
});
}
function deviceTreeListener() {
}
//jSON Configurator Panel
function updateText(content) {
$("#textJsonInput").val(content);
}
//Custom Event Logger Functions
function updateLog(content, status) {
//Gets the Timestamp and inserts the content passed into the function
if (status == null) {
status = "";
}
var d = new Date(),
h = (d.getHours() < 10 ? '0' : '') + d.getHours(),
m = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
s = (d.getSeconds() < 10 ? '0' : '') + d.getSeconds();
i = h + ':' + m + ':' + s;
//This function updates the log in the Event Log insert a row at the top of the table
var table = document.getElementById("resultsRow");
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = i;
cell2.innerHTML = content;
cell3.innerHTML = status;
}
//KSE Logger Functions
function updateEventLog(timestamp, eventType, message) {
var table = document.getElementById("eventsRow");
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = timestamp;
cell2.innerHTML = eventType;
cell3.innerHTML = message;
}
//Stats Bar functions
function updateStatsBarServer(inputServer) {
//Updates the Server IP
$("#connectedTo").html("<strong>Connected to &#58</strong>" + "<a href = \"http://" + inputServer + "/config\" target=\"_blank\"</a>" + inputServer + "</li>");
}
function updateStatsBarChannelCount() {
//Updates the No. of channels. The Global Variable channelCount is written into by the updateProj Function
var count = 0;
for (var i = 0; i < channelList.length; i++) {
count++;
}
$("#channelCount").html("<strong>No. of Channels &#58</strong>" + count + "</li>");
}
function updateStatsDeviceCount() {
var count = 0;
if (channelList === undefined) {
count = 0;
} else {
for (var i = 0; i < channelList.length; i++) {
count = count + channelList[i].children.length;
}
}
$("#deviceCount").html("<strong>No. of Devices &#58</strong>" + count + "</li>");
}
function readProj() {
//This function is a single read to the projObj
//Upon the sucessful callback, we update the global variables to make them universally accessible
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function() {
connectState = true;
updateLog("Server is now connected to " + inputServer, status);
},
error: function() {
connectState = false;
updateLog("Please check your connection and configuration", status);
}
});
}
function updateProj(inputServer) {
////This function is used in the Loop function to update the Global Variable projObj
//The following global variables are updated here: projObj
//Upon the sucessful callback, we update the global variables to make them universally accessible
if (connectState) {
//make sure the user wants to stay connected and avoid a situation we continue to update even when the user wants to disconnect
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(JSON) {
//success(result,status,xhr)
projObj = JSON;
var tempList = [];
var tempObj = {};
channelCount = JSON.length;
for (var i = 0; i < channelCount; i++) {
tempObj = {};
tempObj.text = projObj[i]["common.ALLTYPES_NAME"];
tempObj.driver = projObj[i]["servermain.MULTIPLE_TYPES_DEVICE_DRIVER"];
getDevicesList(projObj[i]["common.ALLTYPES_NAME"]);
tempList[i] = tempObj;
}
var tempStr = "";
var tempStr2 = "";
for (var i = 0; i < tempList.length; i++) {
tempStr += tempList[i].text;
}
for (var i = 0; i < channelList.length; i++) {
tempStr2 += channelList[i].text;
}
if (tempStr == tempStr2) {
//we compare the list before writing again to avoid corruption of the data
//console.log("List unchanged");
} else {
channelList = tempList;
//console.log("List Updated");
treeChanged = true;
}
},
error: function(JSON, status, xhr) {
updateLog("Server is Disconnected..", xhr.statusText);
disconnected = true;
}
});
}
}
function channelSelected(channelName, driverType) {
//This function takes a server ip and returns the jSON response
//Upon the sucessful callback, we update the global variables to make them universally accessible
//Shows up the Channel Panel under Asset Creation
$(cselected).toggleClass("expanded");
$("#displayChannelPanel").addClass("active");
$("#displayDevicePanel").removeClass("active");
$("#displayTagPanel").removeClass("active");
$("#channelPanel").show();
$("#devicePanel").hide();
$("#tagPanel").hide();
$("#channel").val(channelName);
$("#channelType").val(driverType);
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/' + channelName + '/devices',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(data) {
//Updates the json Text Input and the Json Tree View
editor.set(data);
updateText(JSON.stringify(data));
console.log(data);
document.getElementById("deviceId").value = data[0]["servermain.DEVICE_ID_STRING"];
document.getElementById("device").value = data[0]["common.ALLTYPES_NAME"];
},
error: function() {}
});
}
function deviceSelected(deviceName, channelName) {
$("#displayChannelPanel").removeClass("active");
$("#displayDevicePanel").addClass("active");
$("#displayTagPanel").removeClass("active");
$("#channelPanel").hide();
$("#devicePanel").show();
$("#tagPanel").hide();
$("#deviceName").val(deviceName);
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/' + channelName + '/devices/' + deviceName,
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(data) {
//Updates the json Text Input and the Json Tree View
updateText(JSON.stringify(data));
editor.set(data);
$("#deviceId").val(data["servermain.DEVICE_ID_STRING"]);
$("#channelType").val(data["servermain.MULTIPLE_TYPES_DEVICE_DRIVER"]);
inputDevIDOld = data["servermain.DEVICE_ID_STRING"];
console.log(inputDevIDOld);
},
error: function() {
}
});
}
//OPERATIONS THAT GET INPUTS
function loadMdbsFile() {
//var url = string(document.getElementById("importMdbsJSON").value); //future improvement?
$("#displayText").addClass("active");
$("#displayTree").removeClass("active");
$("#displayTagList").removeClass("active");
$("#textJsonEditor").show();
$("#jsonEditorContainer").hide();
$("#tagListContainer").hide();
var url = "Modbus.txt";
var result = "";
var stringJson = "";
$.ajax({
type: 'GET',
url: url,
dataType: 'text',
success: function(data) {
result = data;
//Update text field wiht JSON from file
updateText(result);
//Parse JSON into the fields for object creation/update
inputJSON = document.getElementById('textJsonInput');
parsedJSON = JSON.parse(inputJSON.value);
//alert(parsedJSON['common.ALLTYPES_NAME']); //debug alert
inputChannel = parsedJSON['common.ALLTYPES_NAME'];
inputChannelType = parsedJSON['servermain.MULTIPLE_TYPES_DEVICE_DRIVER'];
inputDevice = parsedJSON['common.ALLTYPES_DEVNAME'];
inputDevID = parsedJSON['servermain.DEVICE_ID_STRING'];
inputTag = parsedJSON['common.ALLTYPES_TAGNAME'];
inputTagAddr = parsedJSON['servermain.TAG_ADDRESS'];
inputTagType = parsedJSON['servermain.TAG_DATA_TYPE'];
document.getElementById("channel").value = inputChannel;
document.getElementById("channelType").value = inputChannelType;
document.getElementById("device").value = inputDevice;
document.getElementById("deviceId").value = inputDevID;
document.getElementById("tag").value = inputTag;
document.getElementById("tagAddr").value = inputTagAddr;
document.getElementById("tagType").value = inputTagType;
},
});
}
function loadABFile() {
//var url = string(document.getElementById("importMdbsJSON").value); //future improvement?
$("#displayText").addClass("active");
$("#displayTree").removeClass("active");
$("#displayTagList").removeClass("active");
$("#textJsonEditor").show();
$("#jsonEditorContainer").hide();
$("#tagListContainer").hide();
var url = "AB.txt";
var result = "";
var stringJson = "";
$.ajax({
type: 'GET',
url: url,
dataType: 'text',
success: function(data) {
result = data;
//Update text field wiht JSON from file
updateText(result);
//Parse JSON into the fields for object creation/update
inputJSON = document.getElementById('textJsonInput');
parsedJSON = JSON.parse(inputJSON.value);
//alert(parsedJSON['common.ALLTYPES_NAME']); //debug alert
inputChannel = parsedJSON['common.ALLTYPES_NAME'];
inputChannelType = parsedJSON['servermain.MULTIPLE_TYPES_DEVICE_DRIVER'];
inputDevice = parsedJSON['common.ALLTYPES_DEVNAME'];
inputDevID = parsedJSON['servermain.DEVICE_ID_STRING'];
inputTag = parsedJSON['common.ALLTYPES_TAGNAME'];
inputTagAddr = parsedJSON['servermain.TAG_ADDRESS'];
inputTagType = parsedJSON['servermain.TAG_DATA_TYPE'];
document.getElementById("channel").value = inputChannel;
document.getElementById("channelType").value = inputChannelType;
document.getElementById("device").value = inputDevice;
document.getElementById("deviceId").value = inputDevID;
document.getElementById("tag").value = inputTag;
document.getElementById("tagAddr").value = inputTagAddr;
document.getElementById("tagType").value = inputTagType;
},
});
}
function getDevicesList(channelName) {
//This function takes in a Channel Name and addes the list of devices into the global object Channel List
//e.g. getDevicesList(Modbus TCP/IP);
$.ajax({
//An ajax call to the end point for the "Modbus TCP/IP"
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/' + channelName + '/devices',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(data) {
var tempList = [];
var tempDeviceModelList = [];
//Loops through the returned JSON and writes into an array of devices
for (var i = 0; i < data.length; i++) {
tempList[i] = data[i]["common.ALLTYPES_NAME"];
tempDeviceModelList[i] = data[i]["servermain.DEVICE_MODEL"];
}
// The temp list is created. E.g.{16 Bit Device,8 Bit Device}
for (var j = 0; j < channelCount; j++) {
//We now look for the obj that belongs to the channel name in channelList
if (channelList[j].text == channelName) {
//console.log(channelList[j].text + " Found");
//Trying to recreate the same format and do the comparison
var tempArray = [];
var tempObj = {};
tempObj.text = channelName;
tempObj.children = tempList;
tempObj.deviceModel = tempDeviceModelList;
tempArray[1] = tempObj;
var string1 = JSON.stringify(channelList[j].children);
var string2 = JSON.stringify(tempArray[1].children);
//Finally we can compare
if (string1 == string2) {
//Device unchanged. No need to do anything
//console.log("Device List for " + channelName + " is same");
} else {
//Device List is different. Add in the new list
//console.log("Device List for " + channelName + " is different");
channelList[j].children = tempList;
channelList[j].deviceModel = tempDeviceModelList;
//console.log("Added Children List for " + channelName);
treeChanged = true;
}
}
}
},
error: function() {
updateLog("Error getting device for " + channelName + "in getDeviceList");
}
});
}
function getChannelProperties(channelName) {
// retrieves the Channel Properies based on input
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/drivers/channels/' + channelName,
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
success: function(data, status, xhr) {
//console.log(xhr.responseText);
},
error: function(data, status, xhr) {
//console.log(data);
}
});
}
function getTags(deviceName, channelName) {
$("#displayTagList").addClass("active");
$("#displayText").removeClass("active");
$("#displayTree").removeClass("active");
$("#textJsonEditor").hide();
$("#jsonEditorContainer").hide();
$("#tagListContainer").show();
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/' + channelName + '/devices/' + deviceName + '/tags',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(data) {
var readresultsview = "<tr align=" + 'left' + "><th>Tag Name</th><th>Address</th></tr>";
for (var i = 0; i < data.length; i++) {
readresultsview += "<td>" + data[i]["common.ALLTYPES_NAME"] + "</td><td>" + data[i]["servermain.TAG_ADDRESS"] + "</td></tr>";
}
document.getElementById("tagReadResults").innerHTML = readresultsview;
},
error: function() {}
});
}
function updateTags(deviceName, channelName) {
console.log("Refreshing Tag List");
$.ajax({
type: 'GET',
url: 'http://' + inputServer + '/config/v1/project/channels/' + channelName + '/devices/' + deviceName + '/tags',
contentType: 'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Authorization': 'Basic ' + encodeAuth
},
dataType: "json",
success: function(data) {
var readresultsview = "<tr align=" + 'left' + "><th>Tag Name</th><th>Address</th></tr>";
for (var i = 0; i < data.length; i++) {
readresultsview += "<td>" + data[i]["common.ALLTYPES_NAME"] + "</td><td>" + data[i]["servermain.TAG_ADDRESS"] + "</td></tr>";
}
document.getElementById("tagReadResults").innerHTML = readresultsview;
},
error: function() {}
});
}
//Unfortunately, we do not provide a list of drivers via the API yet. We therefore hardcoded the enumerated data. Please refer to the documentation for more information
function retreiveDeviceModel(driver, model) {
if (driver == "Modbus TCP/IP Ethernet") {
switch (model) {
case 0:
return "Modbus";
case 1:
return "Mailbox";
case 2:
return "Instromet";
case 3:
return "Roxar RFM";
case 4:
return "Fluenta FGM";
case 5:
return "Applicom";
case 6:
return "CEG";
default:
return "";
}
}
if (driver == "Simulator") {
switch (model) {
case 0:
return "16 Bit Device";
case 1:
return "8 Bit Device ";
default:
return "";
}
}
}