//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 = "
  • You are now connected as : " + userName + "
  • "; $("#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("Connected to :" + "" + inputServer + ""); } 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("No. of Channels :" + count + ""); } 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("No. of Devices :" + count + ""); } 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 = "Tag NameAddress"; for (var i = 0; i < data.length; i++) { readresultsview += "" + data[i]["common.ALLTYPES_NAME"] + "" + data[i]["servermain.TAG_ADDRESS"] + ""; } 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 = "Tag NameAddress"; for (var i = 0; i < data.length; i++) { readresultsview += "" + data[i]["common.ALLTYPES_NAME"] + "" + data[i]["servermain.TAG_ADDRESS"] + ""; } 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 ""; } } }