summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSudhakarKuma2021-10-16 03:00:23 +0530
committerSudhakarKuma2021-10-16 03:00:23 +0530
commit8af2b08163081070b696e90a2030aab2b32694b2 (patch)
tree9b54f694432ac097ea5e06a9705eb7a498b7f4b1
parentdaaaf4d7f17890bf50fb755296806e164a523d60 (diff)
downloadOM-OPCUA-Control-8af2b08163081070b696e90a2030aab2b32694b2.tar.gz
OM-OPCUA-Control-8af2b08163081070b696e90a2030aab2b32694b2.tar.bz2
OM-OPCUA-Control-8af2b08163081070b696e90a2030aab2b32694b2.zip
Add batch distillation column files
-rw-r--r--Batch-Distillation-Column/BatchDistCntr.py123
-rw-r--r--Batch-Distillation-Column/FlatControlTBReal.mo179
-rw-r--r--Batch-Distillation-Column/FlatControlTBRealExt.mo140
-rw-r--r--Batch-Distillation-Column/FlatControlTBRealExt_res-opcua.matbin0 -> 3322644 bytes
-rwxr-xr-xfind_node_ids.py59
5 files changed, 501 insertions, 0 deletions
diff --git a/Batch-Distillation-Column/BatchDistCntr.py b/Batch-Distillation-Column/BatchDistCntr.py
new file mode 100644
index 0000000..3fc0711
--- /dev/null
+++ b/Batch-Distillation-Column/BatchDistCntr.py
@@ -0,0 +1,123 @@
+# XD[1] 129, XD1SP, XD2SP, D, XD[2] 130, product[2] 133, XB[3] 128, XB3SP
+# valveProduct[1] 435, valveSlop[1] 437, valveProduct[2] 436, valveSlop[2] 438
+
+from opcua import Client, ua
+import time
+import logging
+from tclab import clock
+import pandas as pd
+
+# Define the URL on which the server is broadcasting
+url = "opc.tcp://192.168.0.171:4841"
+
+if __name__ == "__main__":
+ client = Client(url)
+ logging.basicConfig(level=logging.WARN)
+
+ try:
+ client.connect()
+ print("Client Connected")
+
+ enableStopTime = client.get_node(ua.NodeId(10003, 0))
+ # enableStopTime.set_value(False)
+ print("Current state of enableStopTime : {}".format(enableStopTime.get_value()))
+
+ run = client.get_node(ua.NodeId(10001, 0))
+ run.set_value(True)
+ print("Current state of run : {}".format(run.get_value()))
+
+ objects = client.get_objects_node()
+
+ XB3_ID, XD1_ID, XD2_ID = 129, 130, 131 # readIDs
+ D_ID = 440 # readIDs
+ product1_ID, product2_ID = 133, 134 # readIDs
+ slop1_ID, slop2_ID = 141, 142 # readIDs
+ HB_ID = 6 # readIDs
+
+ valveProduct1_ID, valveProduct2_ID = 436, 437 # writeIDs
+ valveSlop1_ID, valveSlop2_ID = 438, 439 # writeIDs
+ readTime_ID = 5 # time ID
+
+ modelicaId = {}
+ modelicaId = objects.get_children()
+ # print(modelicaId)
+
+ XD1SP, XD2SP, XB3SP = 0.95, 0.95, 0.95
+
+ tfinal = 16000
+ stepsize = tfinal / 500
+ XD_1, XD_2, product_1, product_2, slop_1, slop_2, HB, timeVal = [], [], [], [], [], [], [], []
+
+ t = 0
+
+ while True:
+
+ print("Local time is {}".format(t))
+ print("Server time is {}".format(modelicaId[readTime_ID].get_value()))
+
+ XD_1.append(modelicaId[XD1_ID].get_value())
+ XD_2.append(modelicaId[XD2_ID].get_value())
+
+ product_1.append(modelicaId[product1_ID].get_value())
+ product_2.append(modelicaId[product2_ID].get_value())
+
+ slop_1.append(modelicaId[slop1_ID].get_value())
+ slop_2.append(modelicaId[slop2_ID].get_value())
+
+ HB.append(modelicaId[HB_ID].get_value())
+
+ timeVal.append(t)
+
+ if(modelicaId[XD1_ID].get_value() >= XD1SP):
+ print("I am in first loop")
+ modelicaId[valveProduct1_ID].set_value(1.0)
+ modelicaId[valveSlop1_ID].set_value(0.0)
+ modelicaId[valveProduct2_ID].set_value(0.0)
+ modelicaId[valveSlop2_ID].set_value(0.0)
+
+ elif(modelicaId[D_ID].get_value() > 0.0 and modelicaId[XD1_ID].get_value() < XD1SP and \
+ modelicaId[XD2_ID].get_value() < XD2SP and modelicaId[product2_ID].get_value() <= 3e-5):
+ print("I am in second loop")
+ modelicaId[valveProduct1_ID].set_value(0.0)
+ modelicaId[valveSlop1_ID].set_value(1.0)
+ modelicaId[valveProduct2_ID].set_value(0.0)
+ modelicaId[valveSlop2_ID].set_value(0.0)
+
+ elif(modelicaId[D_ID].get_value() > 0.0 and modelicaId[XD2_ID].get_value() >= XD2SP):
+ print("I am in third loop")
+ modelicaId[valveProduct1_ID].set_value(0.0)
+ modelicaId[valveSlop1_ID].set_value(0.0)
+ modelicaId[valveProduct2_ID].set_value(1.0)
+ modelicaId[valveSlop2_ID].set_value(0.0)
+
+ elif(modelicaId[product2_ID].get_value() > 3e-5 and modelicaId[XD2_ID].get_value() < XD2SP \
+ and modelicaId[XB3_ID].get_value() < XB3SP):
+ print("I am in the 4th loop")
+ modelicaId[valveProduct1_ID].set_value(0.0)
+ modelicaId[valveSlop1_ID].set_value(0.0)
+ modelicaId[valveProduct2_ID].set_value(0.0)
+ modelicaId[valveSlop2_ID].set_value(1.0)
+
+ else:
+ print("I am in the last loop")
+ modelicaId[valveProduct1_ID].set_value(0.0)
+ modelicaId[valveSlop1_ID].set_value(0.0)
+ modelicaId[valveProduct2_ID].set_value(0.0)
+ modelicaId[valveSlop2_ID].set_value(0.0)
+
+ t = t + stepsize
+ time.sleep(stepsize)
+ print("="*40)
+
+ except KeyboardInterrupt:
+ print("Stopping sequence!")
+
+ finally:
+ dict = {'time': timeVal, 'XD[1]': XD_1, 'XD[2]': XD_2, \
+ 'product[1]': product_1, 'product[2]': product_2, \
+ 'slop[1]': slop_1, 'slop[2]': slop_2, \
+ 'HB': HB}
+ df = pd.DataFrame(dict)
+ df.to_csv('batchDistExt.csv', index = False)
+ print("Done!")
+ client.disconnect()
diff --git a/Batch-Distillation-Column/FlatControlTBReal.mo b/Batch-Distillation-Column/FlatControlTBReal.mo
new file mode 100644
index 0000000..29f4353
--- /dev/null
+++ b/Batch-Distillation-Column/FlatControlTBReal.mo
@@ -0,0 +1,179 @@
+model FlatControlTBReal
+parameter Integer C = 3 "No of Components", N('No of Trays') = 40 "No of Trays";
+ parameter Real XB0[C] = {0.3, 0.3, 0.4} "Initial Mole Fraction", alpha[C] = {9, 3, 1} "Relative Votality";
+ parameter Real HB0 = 300 "Initial Charge to Still", HD = 10 "Reflux Drum Hold Up", HN = 1 "Tray Hold Up", V = 100 / HR "Vapor Boil up rate", XD1SP = 0.95, XD2SP = 0.95, XB3SP = 0.95 "Specified Product Purity", RR = 1.22 "Reflux Ratio", HR = 3600 "TIme Conversion factor", Epsilon = 1e-5, simulationScalingFactor = 1;
+ Real HB "Still Hold up", XB[C](each min = 0, each max = 1) "Mole fraction in still", YB[C](each min = 0, each max = 1), L "Liquid Flow Rate", X[N, C](each min = 0, each max = 1) "Comp on Trays", Y[N, C](each min = 0, each max = 1), XD[C](each min = 0, each max = 1) "Composition of Distillate", D "Distillate flow rate";
+ //===================================================================================================================*/
+ Real flagProduct[C - 1](each start = -1), flagSlop[C - 1](each start = -1) "flagProduct signalling collection of Product 1 and Product 2. flagSlop signalling collection of Slop 1 and Slop 2";
+ Real timeProduct[C](each start = 0), timeSlop[C - 1](each start = 0) "Times at which products and slops are withdrawn";
+ Real product[C - 1](each start = 3e-5), slop[C - 1](each start = 3e-5) "Holdup tanks for Products and slops";
+ Real productComponents[C - 1, C] "Amounts collected in Product tanks";
+ Real heavyKeyComponentMoles "Quantity (moles) of h.k. component collected in still pot";
+ Real sumProduct[C - 1] "Total number of moles collected in product tanks";
+ Real averageProductMoleFraction[C - 1, C] "Average concentrations comp. in product tanks";
+ Real slopComponents[C - 1, C] "Amounts of comp collected in slop tanks";
+ Real sumSlop[C - 1] "Total number of moles collected in slop tanks";
+ Real averageSlopMoleFraction[C - 1, C] "Average concentrations comp in slop tanks";
+// Boolean valveProduct[C - 1](each start = false), valveSlop[C - 1](each start = false) "On/Off valves for the product and slop tanks";
+ Real valveProduct[C - 1], valveSlop[C - 1] "On/Off valves for the product and slop tanks";
+ //======================================================================================================================*/
+initial equation
+ for i in 1:C - 1 loop
+ for j in 1:C loop
+ productComponents[i, j] = Epsilon "Initial amounts(moles) present in product tanks.";
+ end for;
+ end for;
+ for i in 1:C - 1 loop
+ for j in 1:C loop
+ slopComponents[i, j] = Epsilon "Initial amounts(moles) present in slop tanks.";
+ end for;
+ end for;
+//------------------------------------------------------------------------------------------------------
+ HB = HB0 - HD - N*HN - D;
+ XB[1] = 0.3;
+ XB[2] = 0.3;
+ XB[3] = 0.4;
+ for n in 2:N - 1 loop
+ X[n, 1] = 0.3;
+ X[n, 2] = 0.3;
+ X[n, 3] = 0.4;
+ end for;
+ XD[1] = 0.3;
+ XD[2] = 0.3;
+ XD[3] = 0.4;
+ X[N, 1] = 0.3;
+ X[N, 2] = 0.3;
+ X[N, 3] = 0.4;
+ X[1, 1] = 0.3;
+ X[1, 2] = 0.3;
+ X[1, 3] = 0.4;
+//======================================================================================================
+equation
+/* ====Conditions for getting Time of Products and amount of Heavy Key==== */
+ for i in 1:C - 1 loop
+ when flagProduct[i] == 1 then
+ timeProduct[i] = time;
+ end when;
+ when flagSlop[i] == 1 then
+ timeSlop[i] = time;
+ end when;
+ end for;
+ when valveSlop[C - 1] == 0.0 and timeSlop[C - 1] > 0 then
+ timeProduct[C] = time;
+ end when;
+ when timeProduct[C] > 0 then
+ heavyKeyComponentMoles = HB * XB[3] "Amount of H.K. component recovered";
+ end when;
+//--------------------------------------------------------------------------------------------------------------------
+/* ============ "Amounts ofcomp collected in tank product1 at any point in time"========*/
+ for i in 1:C - 1 loop
+ if valveProduct[i] == 1.0 then
+// Product valve is open.
+ flagProduct[i] = 1 "Removing product 1";
+ flagSlop[i] = -1;
+ der(product[i]) = D;
+ der(slop[i]) = 0;
+ for j in 1:C loop
+ der(productComponents[i, j]) = D * XD[j];
+ der(slopComponents[i, j]) = 0;
+ end for;
+ elseif valveSlop[i] == 1.0 then
+// Slop Valve is open.
+ flagProduct[i] = -1;
+ flagSlop[i] = 1 "Removing Slop 1";
+ der(product[i]) = 0;
+ der(slop[i]) = D;
+ for j in 1:C loop
+ der(productComponents[i, j]) = 0;
+ der(slopComponents[i, j]) = D * XD[j];
+ end for;
+ else
+ flagProduct[i] = -1;
+ flagSlop[i] = -1;
+ der(product[i]) = 0;
+ der(slop[i]) = 0;
+ for j in 1:C loop
+ der(productComponents[i, j]) = 0;
+ der(slopComponents[i, j]) = 0;
+ end for;
+ end if;
+ end for;
+//-----------------------------------------------------------------------------------------------------
+/*============ Total Amount of Products and Components in Slop and Products Tanks===============*/
+ for i in 1:C - 1 loop
+ sumProduct[i] = sum(productComponents[i, :]);
+ sumSlop[i] = sum(slopComponents[i, :]);
+ for j in 1:C loop
+ averageProductMoleFraction[i, j] = productComponents[i, j] / sumProduct[i] "Average concentrations inside product tanks";
+ averageSlopMoleFraction[i, j] = slopComponents[i, j] / sumSlop[i] "Average concentrations inside slop tanks";
+ end for;
+ end for;
+//--------------------------------------------------------------------------------------------------
+/* ============================ Conditions to Open/Close Valves of Slop and Products =================================*/
+ if XD[1] >= XD1SP then
+ valveProduct[1] = 1.0;
+ valveSlop[1] = 0.0;
+ valveProduct[2] = 0.0;
+ valveSlop[2] = 0.0;
+ elseif D > 0 and XD[1] < XD1SP and XD[2] < XD2SP and product[2] <= 3e-5 then
+ valveProduct[1] = 0.0;
+ valveSlop[1] = 1.0;
+ valveProduct[2] = 0.0;
+ valveSlop[2] = 0.0;
+ elseif D > 0 and XD[2] >= XD2SP then
+ valveProduct[1] = 0.0;
+ valveSlop[1] = 0.0;
+ valveProduct[2] = 1.0;
+ valveSlop[2] = 0.0;
+ elseif product[2] > 3e-5 and XD[2] < XD2SP and XB[3] < XB3SP then
+ valveProduct[1] = 0.0;
+ valveSlop[1] = 0.0;
+ valveProduct[2] = 0.0;
+ valveSlop[2] = 1.0;
+ else
+ valveProduct[1] = 0.0;
+ valveSlop[1] = 0.0;
+ valveProduct[2] = 0.0;
+ valveSlop[2] = 0.0;
+ end if;
+/* ==================================================================================================================== */
+/* ===================== Material Balance on Column =========================================*/
+//Initially operated at Total reflux
+ when XD[1] >= XD1SP then
+ D = 40/HR;//V / (1 + RR);
+ end when;
+//------------------------------------------------------------------------------------------------------
+/* ============================ STILL POT ============================================================*/
+ der(HB) = -D;
+ for j in 1:C loop
+ der(HB * XB[j]) = L * X[1, j] - V * YB[j];
+ YB[j] = alpha[j] * XB[j] / (alpha[1] * XB[1] + alpha[2] * XB[2] + alpha[3] * XB[3]);
+ end for;
+/* ============================ N TRAY(Excluding Top and Bottom)======================================*/
+ for n in 2:N - 1 loop
+ for j in 1:C loop
+ HN * der(X[n, j]) = L * (X[n + 1, j] - X[n, j]) + V * (Y[n - 1, j] - Y[n, j]);
+ Y[n, j] = alpha[j] * X[n, j] / (alpha[1] * X[n, 1] + alpha[2] * X[n, 2] + alpha[3] * X[n, 3]);
+ end for;
+ end for;
+/* ============================ Bottom Tray ==========================================================*/
+ for j in 1:C loop
+ HN * der(X[1, j]) = L * (X[2, j] - X[1, j]) + V * (YB[j] - Y[1, j]);
+ Y[1, j] = alpha[j] * X[1, j] / (alpha[1] * X[1, 1] + alpha[2] * X[1, 2] + alpha[3] * X[1, 3]);
+ end for;
+/* ============================ Top Tray =============================================================*/
+ for j in 1:C loop
+ HN * der(X[N, j]) = L * (XD[j] - X[N, j]) + V * (Y[N - 1, j] - Y[N, j]);
+ Y[N, j] = alpha[j] * X[N, j] / (alpha[1] * X[N, 1] + alpha[2] * X[N, 2] + alpha[2] * X[N, 3]);
+ end for;
+/* ============================ REFLUX DRUM ==========================================================*/
+ for j in 1:C loop
+ HD * der(XD[j]) = V * Y[N, j] - (L + D) * XD[j];
+ end for;
+ L = V - D;
+
+ when XB[3] >= XB3SP then
+ terminate("done");
+ end when;
+
+end FlatControlTBReal; \ No newline at end of file
diff --git a/Batch-Distillation-Column/FlatControlTBRealExt.mo b/Batch-Distillation-Column/FlatControlTBRealExt.mo
new file mode 100644
index 0000000..bb4c801
--- /dev/null
+++ b/Batch-Distillation-Column/FlatControlTBRealExt.mo
@@ -0,0 +1,140 @@
+model FlatControlTBRealExt
+ parameter Integer C = 3 "Number of Components", N = 40 "Number of Trays";
+ parameter Real XB0[C] = {0.3, 0.3, 0.4} "Initial Mole Fraction", alpha[C] = {9, 3, 1} "Relative Votality";
+ parameter Real HB0 = 300 "Initial still charge", HD = 10 "Reflux Drum Hold Up", HN = 1 "Tray Hold Up", V = 100 / HR "Vapor Boil up rate", XD1SP = 0.95, XD2SP = 0.95, XB3SP = 0.95 "Specified Product Purity", RR = 1.22 "Reflux Ratio", HR = 3600 "TIme Conversion factor", Epsilon = 1e-5, simulationScalingFactor = 1;
+ Real HB "Still Hold up", XB[C](each min = 0, each max = 1) "Mole fraction in still", YB[C](each min = 0, each max = 1), L "Liquid Flow Rate", X[N, C](each min = 0, each max = 1) "Comp on Trays", Y[N, C](each min = 0, each max = 1), XD[C](each min = 0, each max = 1) "Composition of Distillate", D "Distillate flow rate";
+ //===================================================================================================================*/
+ Real flagProduct[C - 1](each start = -1), flagSlop[C - 1](each start = -1) "flagProduct signalling collection of Product 1 and Product 2. flagSlop signalling collection of Slop 1 and Slop 2";
+ Real timeProduct[C](each start = 0), timeSlop[C - 1](each start = 0) "Times at which products and slops are withdrawn";
+ Real product[C - 1](each start = 3e-5), slop[C - 1](each start = 3e-5) "Holdup tanks for Products and slops";
+ Real productComponents[C - 1, C] "Amounts collected in Product tanks";
+ Real heavyKeyComponentMoles "Quantity (moles) of h.k. component collected in still pot";
+ Real sumProduct[C - 1] "Total number of moles collected in product tanks";
+ Real averageProductMoleFraction[C - 1, C] "Average concentrations comp. in product tanks";
+ Real slopComponents[C - 1, C] "Amounts of comp collected in slop tanks";
+ Real sumSlop[C - 1] "Total number of moles collected in slop tanks";
+ Real averageSlopMoleFraction[C - 1, C] "Average concentrations comp in slop tanks";
+ input Real valveProduct[C - 1], valveSlop[C - 1] "On/Off valves for the product and slop tanks";
+ //======================================================================================================================*/
+initial equation
+ for i in 1:C - 1 loop
+ for j in 1:C loop
+ productComponents[i, j] = Epsilon "Initial amounts(moles) present in product tanks.";
+ end for;
+ end for;
+ for i in 1:C - 1 loop
+ for j in 1:C loop
+ slopComponents[i, j] = Epsilon "Initial amounts(moles) present in slop tanks.";
+ end for;
+ end for;
+//------------------------------------------------------------------------------------------------------
+ HB = HB0 - HD - N*HN - D;
+ XB[1] = 0.3; XB[2] = 0.3; XB[3] = 0.4;
+ for n in 2:N - 1 loop
+ X[n, 1] = 0.3; X[n, 2] = 0.3; X[n, 3] = 0.4;
+ end for;
+ XD[1] = 0.3; XD[2] = 0.3; XD[3] = 0.4;
+ X[N, 1] = 0.3; X[N, 2] = 0.3; X[N, 3] = 0.4;
+ X[1, 1] = 0.3; X[1, 2] = 0.3; X[1, 3] = 0.4;
+//======================================================================================================
+equation
+/* ====Conditions for getting Time of Products and amount of Heavy Key==== */
+ for i in 1:C - 1 loop
+ when flagProduct[i] == 1 then
+ timeProduct[i] = time;
+ end when;
+ when flagSlop[i] == 1 then
+ timeSlop[i] = time;
+ end when;
+ end for;
+ when valveSlop[C - 1] == 0.0 and timeSlop[C - 1] > 0 then
+ timeProduct[C] = time;
+ end when;
+ when timeProduct[C] > 0 then
+ heavyKeyComponentMoles = HB * XB[3] "Amount of H.K. component recovered";
+ end when;
+//--------------------------------------------------------------------------------------------------------------------
+/* ============ "Amounts ofcomp collected in tank product1 at any point in time"========*/
+ for i in 1:C - 1 loop
+ if valveProduct[i] == 1.0 then
+// Product valve is open.
+ flagProduct[i] = 1 "Removing product 1";
+ flagSlop[i] = -1;
+ der(product[i]) = D;
+ der(slop[i]) = 0;
+ for j in 1:C loop
+ der(productComponents[i, j]) = D * XD[j];
+ der(slopComponents[i, j]) = 0;
+ end for;
+ elseif valveSlop[i] == 1.0 then
+// Slop Valve is open.
+ flagProduct[i] = -1;
+ flagSlop[i] = 1 "Removing Slop 1";
+ der(product[i]) = 0;
+ der(slop[i]) = D;
+ for j in 1:C loop
+ der(productComponents[i, j]) = 0;
+ der(slopComponents[i, j]) = D * XD[j];
+ end for;
+ else
+ flagProduct[i] = -1;
+ flagSlop[i] = -1;
+ der(product[i]) = 0;
+ der(slop[i]) = 0;
+ for j in 1:C loop
+ der(productComponents[i, j]) = 0;
+ der(slopComponents[i, j]) = 0;
+ end for;
+ end if;
+ end for;
+//-----------------------------------------------------------------------------------------------------
+/*============ Total Amount of Products and Components in Slop and Products Tanks===============*/
+ for i in 1:C - 1 loop
+ sumProduct[i] = sum(productComponents[i, :]);
+ sumSlop[i] = sum(slopComponents[i, :]);
+ for j in 1:C loop
+ averageProductMoleFraction[i, j] = productComponents[i, j] / sumProduct[i] "Average concentrations inside product tanks";
+ averageSlopMoleFraction[i, j] = slopComponents[i, j] / sumSlop[i] "Average concentrations inside slop tanks";
+ end for;
+ end for;
+
+/* ===================== Material Balance on Column =========================================*/
+//Initially operated at Total reflux
+ when XD[1] >= XD1SP then
+ D = 40/HR;//V / (1 + RR);
+ end when;
+//------------------------------------------------------------------------------------------------------
+/* ============================ STILL POT ============================================================*/
+ der(HB) = -D;
+ for j in 1:C loop
+ der(HB * XB[j]) = L * X[1, j] - V * YB[j];
+ YB[j] = alpha[j] * XB[j] / (alpha[1] * XB[1] + alpha[2] * XB[2] + alpha[3] * XB[3]);
+ end for;
+/* ============================ N TRAY(Excluding Top and Bottom)======================================*/
+ for n in 2:N - 1 loop
+ for j in 1:C loop
+ HN * der(X[n, j]) = L * (X[n + 1, j] - X[n, j]) + V * (Y[n - 1, j] - Y[n, j]);
+ Y[n, j] = alpha[j] * X[n, j] / (alpha[1] * X[n, 1] + alpha[2] * X[n, 2] + alpha[3] * X[n, 3]);
+ end for;
+ end for;
+/* ============================ Bottom Tray ==========================================================*/
+ for j in 1:C loop
+ HN * der(X[1, j]) = L * (X[2, j] - X[1, j]) + V * (YB[j] - Y[1, j]);
+ Y[1, j] = alpha[j] * X[1, j] / (alpha[1] * X[1, 1] + alpha[2] * X[1, 2] + alpha[3] * X[1, 3]);
+ end for;
+/* ============================ Top Tray =============================================================*/
+ for j in 1:C loop
+ HN * der(X[N, j]) = L * (XD[j] - X[N, j]) + V * (Y[N - 1, j] - Y[N, j]);
+ Y[N, j] = alpha[j] * X[N, j] / (alpha[1] * X[N, 1] + alpha[2] * X[N, 2] + alpha[2] * X[N, 3]);
+ end for;
+/* ============================ REFLUX DRUM ==========================================================*/
+ for j in 1:C loop
+ HD * der(XD[j]) = V * Y[N, j] - (L + D) * XD[j];
+ end for;
+ L = V - D;
+
+ when XB[3] >= XB3SP then
+ terminate("Terminate the simulation");
+ end when;
+
+end FlatControlTBRealExt; \ No newline at end of file
diff --git a/Batch-Distillation-Column/FlatControlTBRealExt_res-opcua.mat b/Batch-Distillation-Column/FlatControlTBRealExt_res-opcua.mat
new file mode 100644
index 0000000..4cada52
--- /dev/null
+++ b/Batch-Distillation-Column/FlatControlTBRealExt_res-opcua.mat
Binary files differ
diff --git a/find_node_ids.py b/find_node_ids.py
new file mode 100755
index 0000000..e518572
--- /dev/null
+++ b/find_node_ids.py
@@ -0,0 +1,59 @@
+from opcua import Client
+from opcua import ua
+import time
+
+# Define the URL on which the server is broadcasting
+url = "opc.tcp://192.168.0.171:4841"
+
+if __name__ == "__main__":
+ client = Client(url)
+
+ try:
+ client.connect()
+ print("Client connected!")
+
+ enableStopTime = client.get_node(ua.NodeId(10003, 0))
+ # enableStopTime.set_value(False)
+ print("Current state of enableStopTime : {}".format(enableStopTime.get_value()))
+
+ run = client.get_node(ua.NodeId(10001, 0))
+ run.set_value(True)
+ print("Current state of run : {}".format(run.get_value()))
+
+ root = client.get_root_node()
+ print("Root node is : ", root)
+
+ objects = client.get_objects_node()
+ print("Objects\' node is : ", objects)
+
+ while True:
+ modelicaId = {}
+ modelicaVariables = {}
+ tmp = {}
+
+ modelicaId = objects.get_children()
+
+ for i in range(len(modelicaId)):
+ modelicaVariables[i] = modelicaId[i].get_display_name().Text
+ # modelicaVariables[i] = modelicaId[i].get_browse_name()
+
+ # till index 5, we have values like server, run, step, enableStopTime, etc.
+ # So, we begin with 6 to have the actual parameters of the plant.
+ if (i > 5):
+ tmp[i] = modelicaId[i].get_value()
+ print(i, modelicaVariables[i], tmp[i], modelicaId[i].get_array_dimensions())
+
+ else:
+ print(i, modelicaVariables[i])
+ time.sleep(1)
+ print("="*40)
+
+
+ # print(objects.get_children()[6].get_display_name().Text)
+
+ except KeyboardInterrupt:
+ print("Stopping sequence!")
+
+ finally:
+ print("Done!")
+ client.disconnect()