summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuchita Lad2025-04-02 17:13:23 +0530
committerSuchita Lad2025-04-02 17:13:23 +0530
commitb022d2ffddf5591929f7b902961be33165a17cac (patch)
tree16dc6e83d08ec21288235e6c9f9bee164e4cae7f
parenta068b1fd9f936675f81e90f83589923f39c6dc10 (diff)
downloadCommon-Interface-Project-b022d2ffddf5591929f7b902961be33165a17cac.tar.gz
Common-Interface-Project-b022d2ffddf5591929f7b902961be33165a17cac.tar.bz2
Common-Interface-Project-b022d2ffddf5591929f7b902961be33165a17cac.zip
Updated files to store workspace file in task model
-rw-r--r--blocks/eda-frontend/src/components/SchematicEditor/SimulationProperties.js15
-rw-r--r--blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js12
-rw-r--r--blocks/eda-frontend/src/redux/reducers/simulationReducer.js2
-rw-r--r--blocks/simulationAPI/helpers/config.py5
-rw-r--r--blocks/simulationAPI/helpers/ngspice_helper.py105
-rw-r--r--blocks/simulationAPI/helpers/scilab_manager.py336
-rw-r--r--blocks/simulationAPI/tasks.py10
-rw-r--r--blocks/simulationAPI/views.py23
8 files changed, 410 insertions, 98 deletions
diff --git a/blocks/eda-frontend/src/components/SchematicEditor/SimulationProperties.js b/blocks/eda-frontend/src/components/SchematicEditor/SimulationProperties.js
index 05216811..b79ccd72 100644
--- a/blocks/eda-frontend/src/components/SchematicEditor/SimulationProperties.js
+++ b/blocks/eda-frontend/src/components/SchematicEditor/SimulationProperties.js
@@ -44,6 +44,7 @@ const useStyles = makeStyles((theme) => ({
export default function SimulationProperties () {
const title = useSelector(state => state.netlistReducer.title)
const isSimRes = useSelector(state => state.simulationReducer.isSimRes)
+ const scriptTaskId = useSelector(state => state.simulationReducer.scriptTaskId)
const dispatch = useDispatch()
const classes = useStyles()
const [transientAnalysisControlLine, setTransientAnalysisControlLine] = useState({
@@ -86,11 +87,12 @@ export default function SimulationProperties () {
type: 'text/plain'
})
const file = new File([myblob], `${titleA}.xml`, { type: 'text/xml', lastModified: Date.now() })
- sendNetlist(file)
+ const type = 'XCOS'
+ sendNetlist(file, type)
}
- function sendNetlist (file) {
- netlistConfig(file)
+ function sendNetlist (file, type) {
+ netlistConfig(file, type)
.then((response) => {
const res = response.data
const taskId = res.details.task_id
@@ -102,10 +104,15 @@ export default function SimulationProperties () {
}
// Upload the nelist
- function netlistConfig (file) {
+ function netlistConfig (file, type) {
const formData = new FormData()
formData.append('app_name', process.env.REACT_APP_NAME)
formData.append('file', file)
+ formData.append('type', type)
+ if (scriptTaskId) {
+ formData.append('script_task_id', scriptTaskId)
+ }
+
for (const [key, value] of Object.entries(transientAnalysisControlLine)) {
formData.append(key, value)
}
diff --git a/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js b/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js
index e5f20e54..aa335c35 100644
--- a/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js
+++ b/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js
@@ -346,16 +346,15 @@ export function ScriptScreen ({ isOpen, onClose }) {
}
const fetchScriptOutput = async (taskId) => {
- console.log('Fetching script output for task:', taskId)
try {
const response = await api.get(`simulation/get_script_output/${taskId}`)
const data = response.data
setResult(data.output || 'No output available.')
if (data.variables && Array.isArray(data.variables)) {
- console.log('Variables:', data.variables)
setVariables(data.variables)
}
+ return data
} catch (error) {
console.error('Error fetching script output:', error)
setResult('Error fetching script output.')
@@ -379,14 +378,10 @@ export function ScriptScreen ({ isOpen, onClose }) {
const taskId = res.details.task_id
dispatch(setScriptTaskId(taskId))
-
setTimeout(() => {
fetchScriptOutput(taskId)
- .then((response) => {
- if (response.status === 200) {
- const data = response.data
- dispatch(setResult(data.output, data.variables))
- }
+ .then(() => {
+
})
}, 3000)
})
@@ -417,6 +412,7 @@ export function ScriptScreen ({ isOpen, onClose }) {
const resetCode = () => {
dispatch(setSchScriptDump(''))
+ dispatch(setScriptTaskId(''))
setResult('No output yet...')
setVariables('')
diff --git a/blocks/eda-frontend/src/redux/reducers/simulationReducer.js b/blocks/eda-frontend/src/redux/reducers/simulationReducer.js
index 08b3c2d2..3a5f2fb7 100644
--- a/blocks/eda-frontend/src/redux/reducers/simulationReducer.js
+++ b/blocks/eda-frontend/src/redux/reducers/simulationReducer.js
@@ -45,7 +45,7 @@ export default function (state = initialState, action) {
case actions.SET_SCRIPT_TASK_ID: {
return {
...state,
- scriptTaskId: action.payload.taskId
+ scriptTaskId: action.payload.scriptTaskId
}
}
diff --git a/blocks/simulationAPI/helpers/config.py b/blocks/simulationAPI/helpers/config.py
index c1593a68..0db1da84 100644
--- a/blocks/simulationAPI/helpers/config.py
+++ b/blocks/simulationAPI/helpers/config.py
@@ -11,6 +11,8 @@ SCILAB_START_INSTANCES = int(os.environ.get('SCILAB_START_INSTANCES', '2'))
SCILAB_MAX_INSTANCES = int(os.environ.get('SCILAB_MAX_INSTANCES', '3'))
SCILAB_INSTANCE_RETRY_INTERVAL = int(os.environ.get('SCILAB_INSTANCE_RETRY_INTERVAL', '5'))
+SCILAB_INSTANCE_TIMEOUT_INTERVAL = 300
+
# Following are system command which are not permitted in sci files
# (Reference scilab-on-cloud project)
SYSTEM_COMMANDS = (
@@ -22,4 +24,7 @@ SPECIAL_CHARACTERS = r'["\'\\]'
# The directory where images are created
IMAGEDIR = 'images'
+# Set CREATEIMAGE to True to create img_test.jpg in IMAGEDIR
+CREATEIMAGE = False
+
REMOVEFILE = True
diff --git a/blocks/simulationAPI/helpers/ngspice_helper.py b/blocks/simulationAPI/helpers/ngspice_helper.py
index ad4fd778..3b466760 100644
--- a/blocks/simulationAPI/helpers/ngspice_helper.py
+++ b/blocks/simulationAPI/helpers/ngspice_helper.py
@@ -13,6 +13,7 @@ from django.db.models import Case, F, Value, When
from django.utils.timezone import now
from simulationAPI.models import Task
+from simulationAPI.helpers.scilab_manager import start_scilab, upload
logger = get_task_logger(__name__)
XmlToXcos = join(settings.BASE_DIR, 'Xcos/XmlToXcos.sh')
@@ -50,8 +51,13 @@ class CannotRunParser(Exception):
def update_task_status(task_id, status, meta=None):
+ print("status:", status, task_id)
# Update Celery backend state
- current_task.update_state(state=status, meta=meta or {})
+ if current_task is not None:
+ try:
+ current_task.update_state(state=status, meta=meta or {})
+ except Exception as e:
+ print(f"Error updating Celery task state: {e}")
# Update Django database
Task.objects.filter(task_id=task_id).update(
@@ -110,74 +116,47 @@ def CreateXcos(file_path, parameters, task_id):
return xcosfile
-def ExecXml(task, task_name):
+def ExecXml(task, task_name, workspace_file):
task_id = task.task_id
file_path = task.file.path
+
current_dir = settings.MEDIA_ROOT + '/' + str(task_id)
try:
+ # Create xcos file
xcosfile = CreateXml(file_path, task.parameters, task_id)
- (logfilefd, log_name) = mkstemp(prefix=datetime.now().strftime(
- 'scilab-log-%Y%m%d-'), suffix='.txt', dir=current_dir)
-
- if logfilefd != LOGFILEFD:
- os.dup2(logfilefd, LOGFILEFD)
- os.close(logfilefd)
-
- task.log_name = log_name
- task.save()
-
- logger.info('will run %s %s> %s', SCILAB_CMD[0], LOGFILEFD, log_name)
- logger.info('running command %s', SCILAB_CMD[-1])
- proc = subprocess.Popen(
- SCILAB_CMD,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- start_new_session=True, universal_newlines=True, cwd=current_dir,
- pass_fds=(LOGFILEFD, ))
-
- os.close(LOGFILEFD)
-
- update_task_status(task_id, 'STREAMING',
- meta={'current_process': 'Processed Xml, Streaming Output'})
-
- cmd = "try;"
- cmd += "chdir('%s');" % current_dir
- cmd += "loadXcosLibs();"
- cmd += "importXcosDiagram('%s');" % xcosfile
- cmd += "xcos_simulate(scs_m,4);"
- cmd += SCILAB_END
-
- logger.info('running command %s', cmd)
- proc.stdin.write(cmd)
-
- (out, err) = proc.communicate()
-
- maxlines = 15
- logger.info('Ran %s', SCILAB_CMD[0])
- if out:
- out = out.strip()
- if out:
- out = '\n'.join(re.split(r'\n+', out, maxlines + 1)[:maxlines])
- logger.info('out=%s', out)
- if err:
- err = re.sub(r'Undefined variable: helpbrowser_update', '', err)
- err = err.strip()
- if err:
- err = '\n'.join(re.split(r'\n+', err, maxlines + 1)[:maxlines])
- logger.info('err=%s', err)
-
- task.returncode = proc.returncode
- task.save()
-
- return 'Streaming'
+
+ upload(task.session, task, xcosfile)
+ result = start_scilab(task.session, task, xcosfile)
+
+ if result == "":
+ logger.info('Simulation completed successfully for task %s', task_id)
+ update_task_status(task_id, 'SUCCESS',
+ meta={'current_process': 'Simulation Completed'})
+ return 'Streaming'
+ else:
+ logger.warning('Simulation failed for task %s: %s', task_id, result)
+ update_task_status(task_id, 'FAILURE',
+ meta={'current_process': result})
+ return 'Failure'
+
except BaseException as e:
- logger.exception('Encountered Exception:')
- logger.info('removing %s', file_path)
- os.remove(file_path)
+ logger.exception('Encountered Exception during XML Execution:')
+ logger.info('Cleaning up files for task %s', task_id)
+ # Cleanup
+ try:
+ os.remove(file_path)
+ except FileNotFoundError:
+ pass
target = os.listdir(current_dir)
for item in target:
- logger.info('removing %s', item)
- os.remove(join(current_dir, item))
- logger.info('removing %s', current_dir)
- os.rmdir(current_dir)
- logger.info('Deleted Files')
+ try:
+ os.remove(join(current_dir, item))
+ except FileNotFoundError:
+ continue
+ try:
+ os.rmdir(current_dir)
+ except OSError:
+ pass
+ logger.info('Deleted Files and Directory for task %s', task_id)
raise e
+
diff --git a/blocks/simulationAPI/helpers/scilab_manager.py b/blocks/simulationAPI/helpers/scilab_manager.py
index d0b7d8ec..fb693167 100644
--- a/blocks/simulationAPI/helpers/scilab_manager.py
+++ b/blocks/simulationAPI/helpers/scilab_manager.py
@@ -7,8 +7,9 @@ from gevent.event import Event
from gevent.lock import RLock
import glob
import json
+import fileinput
import os
-from os.path import abspath, exists, isfile, join
+from os.path import abspath, exists, isfile, join, splitext
import re
import signal
import subprocess
@@ -18,13 +19,17 @@ from time import time
import unicodedata
import uuid
import logging
+from xml.dom import minidom
+import shutil
from simulationAPI.helpers import config
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blocks.settings')
# Scilab dir
SCILAB_DIR = abspath(settings.SCILAB_DIR)
+READCONTENTFILE = abspath("resources/Read_Content.txt")
SCILAB = join(SCILAB_DIR, 'bin', 'scilab-adv-cli')
BASEDIR = abspath('src/static')
IMAGEDIR = join(BASEDIR, config.IMAGEDIR)
@@ -224,7 +229,7 @@ class UserData:
def __init__(self):
self.sessiondir = mkdtemp(
prefix=datetime.now().strftime('%Y%m%d.'), dir=SESSIONDIR)
- self.diagrams = []
+ self.diagrams = {}
self.datafiles = []
self.scripts = {}
self.scriptcount = 0
@@ -252,7 +257,7 @@ class UserData:
return str(rv)
def clean(self):
- for diagram in self.diagrams:
+ for diagram in self.diagrams.values():
diagram.clean()
self.diagrams = None
for script in self.scripts:
@@ -859,11 +864,11 @@ def getscriptoutput(session, task):
return rv
-def sendfile(session):
+def sendfile(session, task):
'''
This route is used in chart.js for sending image filename
'''
- diagram = get_diagram(session, get_request_id())
+ diagram = get_diagram(session, task)
if diagram is None:
logger.warning('no diagram')
return ''
@@ -945,12 +950,12 @@ def load_variables(filename):
return command
-def start_scilab(session):
+def start_scilab(session, task, xcosfile):
'''
function to execute xcos file using scilab (scilab-adv-cli), access log
file written by scilab
'''
- diagram = get_diagram(session, get_request_id())
+ diagram = get_diagram(session, task)
if diagram is None:
logger.warning('no diagram')
return "error"
@@ -1030,6 +1035,8 @@ def start_scilab(session):
instance = diagram.instance
logger.info('log_name=%s', instance.log_name)
+ task.log_name = instance.log_name
+ task.save()
# Start sending log to chart function for creating chart
try:
@@ -1098,15 +1105,313 @@ def stopDetailsThread(diagram):
remove(fn)
-def get_diagram(session, xcos_file_id, remove=False):
- if not xcos_file_id:
+def upload(session, task, xcosfile):
+ '''Route that will process the file upload'''
+ # Get the file
+ file = xcosfile
+ # Check if the file is not null
+ if not file:
+ return "error"
+ # flags to check if both TOWS_c and FROMWSB are present
+ flag1 = 0
+ flag2 = 0
+ list1 = []
+ list2 = []
+ # Make the filename safe, remove unsupported chars
+ (diagram, scripts, sessiondir) = add_diagram(session, task)
+
+ script = get_script(session, task, scripts=scripts)
+ if script is not None:
+ diagram.workspace_filename = script.workspace_filename
+ # Save the file in xml extension and using it for further modification
+ # by using xml parser
+ temp_file_xml_name = diagram.diagram_id + ".xml"
+ shutil.copy(xcosfile, temp_file_xml_name)
+ # file.save(temp_file_xml_name)
+ new_xml = minidom.parse(temp_file_xml_name)
+
+ # to identify if we have to load or save to workspace or neither #0 if
+ # neither TOWS_c or FROMWSB found
+ blocks = new_xml.getElementsByTagName("BasicBlock")
+ tk_is_present = False
+ pattern = re.compile(r"<SplitBlock")
+ for i, line in enumerate(open(temp_file_xml_name)):
+ for match in re.finditer(pattern, line):
+ list1.append(i + 1)
+ pattern1 = re.compile(r"<ControlPort")
+ for i, line in enumerate(open(temp_file_xml_name)):
+ for match in re.finditer(pattern1, line):
+ list2.append(i + 1)
+ pattern2 = re.compile(r"<ImplicitInputPort")
+ count1 = 0
+
+ for i, line in enumerate(open(temp_file_xml_name)):
+ for match in re.finditer(pattern2, line):
+ count1 += 1
+ if count1 >= 1:
+ splitline = []
+ count = 0
+ for i in range(len(list1)):
+ for j in range(len(list2)):
+ if list2[j] == list1[i] + 3:
+ count += 1
+ splitline.append(list1[i])
+ blocksplit = new_xml.getElementsByTagName("SplitBlock")
+ block_ids = [] # this stores the id of split blocks
+ for block in blocksplit:
+ if block.getAttribute("style") == "SPLIT_f":
+ block_ids.append(int(block.getAttribute("id")))
+ compsplit = []
+ for i in range(len(splitline)):
+ for j in range(len(list1)):
+ if splitline[i] == list1[j]:
+ compsplit.append(j)
+
+ finalsplit = []
+ for i in range(len(compsplit)):
+ finalsplit.append(block_ids[compsplit[i]])
+
+ blockcontrol = new_xml.getElementsByTagName("ControlPort")
+ for block in blockcontrol:
+ for i in range(len(finalsplit)):
+ # match the lines with the parent of our spliblocks which
+ # we need to change
+ if block.getAttribute("parent") == str(finalsplit[i]):
+ block.setAttribute('id', '-1')
+
+ blockcommand = new_xml.getElementsByTagName("CommandPort")
+ for block in blockcommand:
+ for i in range(len(finalsplit)):
+ if block.getAttribute("parent") == str(finalsplit[i]):
+ block.setAttribute('id', '-1')
+
+ # here we take the ids of command controllink which we will search
+ # and change
+ finalchangeid = []
+ for i in range(len(finalsplit)):
+ finalchangeid.append(finalsplit[i] + 4)
+ finalchangeid.append(finalsplit[i] + 5)
+
+ # here we save the contents
+ with open(temp_file_xml_name, 'w') as f:
+ f.write(new_xml.toxml())
+
+ with open(temp_file_xml_name, "r") as f:
+ newline = []
+ i = 0
+ for word in f.readlines():
+
+ if "<CommandControlLink id=" in word:
+ temp_word = ""
+ for i in range(len(finalchangeid)):
+ fcid = str(finalchangeid[i])
+ srch = '<CommandControlLink id="' + fcid + '"'
+ if srch in word:
+ rplc = '<ImplicitLink id="' + fcid + '"'
+ temp_word = word.replace(srch, rplc)
+ i += 1
+ if temp_word != "":
+ newline.append(temp_word)
+ else:
+ newline.append(word)
+ else:
+ newline.append(word)
+ with open(temp_file_xml_name, "w") as f:
+ for line in newline:
+ f.writelines(line)
+ with open(temp_file_xml_name, "r") as in_file:
+ buf = in_file.readlines()
+ # length=len(finalsplit)
+ # return finalsplit
+ with open(temp_file_xml_name, "w") as out_file:
+ for line in buf:
+ for i in range(len(finalsplit)):
+ fs = str(finalsplit[i])
+ srch = ('<ControlPort connectable="0" '
+ 'dataType="UNKNOW_TYPE" id="-1" ordering="1" '
+ 'parent="' + fs + '"')
+ if srch in line:
+ line = (
+ '\t <ImplicitInputPort connectable="0" '
+ 'dataType="UNKNOW_TYPE" '
+ 'id="' + str(finalsplit[i] + 1) + '" '
+ 'ordering="1" parent="' + fs + '" '
+ 'style="ImplicitInputPort">\n'
+ '\t\t<mxGeometry as="geometry" height="10" '
+ 'relative="1" width="10" y="0.5000">\n'
+ '\t\t</mxGeometry>\n'
+ '\t </ImplicitInputPort>\n'
+ '\t <ImplicitOutputPort connectable="0" '
+ 'dataType="UNKNOW_TYPE" '
+ 'id="' + str(finalsplit[i] + 2) + '" '
+ 'ordering="1" parent="' + fs + '" '
+ 'style="ImplicitOutputPort">\n'
+ '\t\t<mxGeometry as="geometry" height="10" '
+ 'relative="1" width="10" y="0.5000">\n'
+ '\t\t</mxGeometry>\n'
+ '\t </ImplicitOutputPort>\n'
+ '\t <ImplicitOutputPort connectable="0" '
+ 'dataType="UNKNOW_TYPE" '
+ 'id="' + str(finalsplit[i] + 3) + '" '
+ 'ordering="1" parent="' + fs + '" '
+ 'style="ImplicitOutputPort">\n'
+ '\t\t<mxGeometry as="geometry" height="10" '
+ 'relative="1" width="10" y="0.5000">\n'
+ '\t\t</mxGeometry>\n'
+ '\t </ImplicitOutputPort>\n' + line)
+
+ out_file.write(line)
+ list3 = []
+ implitdetect = []
+ # return temp_file_xml_name
+ for i in range(len(finalsplit)):
+ implitdetect.append(finalsplit[i] + 5)
+ implitdetect.append(finalsplit[i] + 6)
+ for i in range(len(implitdetect)):
+ pattern3 = re.compile(
+ "<ImplicitLink id=\"" + str(implitdetect[i]) + "\"")
+ for i, line in enumerate(open(temp_file_xml_name)):
+ for match in re.finditer(pattern3, line):
+ list3.append(i - 1)
+ with open(temp_file_xml_name, 'r+') as f:
+ data = f.read().splitlines()
+ replace = list3
+ for i in replace:
+ data[i] = '\t </ImplicitLink>'
+ f.seek(0)
+ f.write('\n'.join(data))
+ f.truncate()
+ fname = join(sessiondir, UPLOAD_FOLDER,
+ splitext(temp_file_xml_name)[0] + ".xcos")
+ os.rename(temp_file_xml_name, fname)
+ diagram.xcos_file_name = fname
+ return diagram.diagram_id
+
+ # List to contain all affich blocks
+ blockaffich = new_xml.getElementsByTagName("AfficheBlock")
+ for block in blockaffich:
+ interfaceFunctionName = block.getAttribute("interfaceFunctionName")
+ if interfaceFunctionName == "AFFICH_m":
+ diagram.workspace_counter = 4
+
+ # List to contain all the block IDs of tkscales so that we can create
+ # read blocks with these IDs
+ block_id = []
+ for block in blocks:
+ interfaceFunctionName = block.getAttribute("interfaceFunctionName")
+ if interfaceFunctionName == "TKSCALE":
+ block_id.append(block.getAttribute("id"))
+ block.setAttribute('id', '-1')
+ tk_is_present = True
+ # Changed the ID of tkscales to -1 so that virtually the
+ # tkscale blocks get disconnected from diagram at the backend
+ # Taking workspace_counter 1 for TOWS_c and 2 for FROMWSB
+ elif interfaceFunctionName == "scifunc_block_m":
+ diagram.workspace_counter = 5
+ elif interfaceFunctionName == "TOWS_c":
+ if block.childNodes:
+ for node in block.childNodes:
+ if not isinstance(node, minidom.Element):
+ continue
+ if node.getAttribute("as") != "exprs":
+ continue
+ if node.childNodes is None:
+ continue
+ childCount = 0
+ for childChildNode in node.childNodes:
+ if not isinstance(childChildNode, minidom.Element):
+ continue
+ childCount += 1
+ if childCount != 2:
+ continue
+ value = childChildNode.getAttribute("value")
+ if value is not None:
+ diagram.save_variables.add(value)
+ break
+ diagram.workspace_counter = 1
+ flag1 = 1
+ elif interfaceFunctionName == "FROMWSB":
+ diagram.workspace_counter = 2
+ flag2 = 1
+ if diagram.save_variables:
+ logger.info("save variables = %s", diagram.save_variables)
+ if flag1 and flag2:
+ # Both TOWS_c and FROMWSB are present
+ diagram.workspace_counter = 3
+ # Hardcoded the real time scaling to 1.0 (i.e., no scaling of time
+ # occurs) only if tkscale is present
+ if tk_is_present:
+ for dia in new_xml.getElementsByTagName("XcosDiagram"):
+ dia.setAttribute('realTimeScaling', '1.0')
+
+ # Save the changes made by parser
+ with open(temp_file_xml_name, 'w') as f:
+ f.write(new_xml.toxml())
+
+ # In front of block tkscale printing the block corresponding to read
+ # function and assigning corresponding values
+ skipblock = False
+ for line in fileinput.input(temp_file_xml_name, inplace=1):
+
+ if 'interfaceFunctionName=\"TKSCALE\"' in line:
+ # change the block ID
+ i = diagram.tk_count
+ print('<BasicBlock blockType="d" id="', block_id[i], '" '
+ 'interfaceFunctionName="RFILE_f" parent="1" '
+ 'simulationFunctionName="readf" '
+ 'simulationFunctionType="DEFAULT" style="RFILE_f">',
+ sep='')
+ print('<ScilabString as="exprs" height="5" width="1">')
+ print('<data column="0" line="0" value="1"/>')
+ # Value equal to 1 implies take readings from first column in
+ # the file
+ print('<data column="0" line="1" value="2"/>')
+ # Path to the file from which read block obtains the values
+ fname = join(diagram.sessiondir, VALUES_FOLDER,
+ diagram.diagram_id + "_tk" + str(i + 1) + ".txt")
+ print('<data column="0" line="2" value="', fname, '"/>',
+ sep='')
+ print('<data column="0" line="3" value="(2(e10.3,1x))"/>')
+ # (2(e10.3,1x)) The format in which numbers are written
+ # Two columns with base 10 and 3 digits after decimal and 1x
+ # represents 1 unit space between two columns.
+ print('<data column="0" line="4" value="2"/>')
+ print('</ScilabString>')
+ print('<ScilabDouble as="realParameters" '
+ 'height="0" width="0"/>')
+ print('<ScilabDouble as="integerParameters" '
+ 'height="105" width="1">')
+ diagram.tk_count += 1
+ # The remaining part of the block is read from the
+ # Read_Content.txt file and written to the xml file
+ with open(READCONTENTFILE, "r") as read_file:
+ for line_content in read_file:
+ print(line_content, end='')
+ skipblock = True
+ elif skipblock:
+ if '</BasicBlock>' in line:
+ skipblock = False
+ else:
+ print(line, end='')
+
+ # Changing the file extension from xml to xcos
+ fname = join(sessiondir, UPLOAD_FOLDER,
+ splitext(temp_file_xml_name)[0] + ".xcos")
+ # Move the xcos file to uploads directory
+ os.rename(temp_file_xml_name, fname)
+ diagram.xcos_file_name = fname
+ return diagram.diagram_id
+
+
+def get_diagram(session, task, remove=False):
+ if not task:
logger.warning('no id')
return None
- xcos_file_id = int(xcos_file_id)
+ xcos_file_id = task.task_id
(diagrams, __, __, __, __, __, __) = init_session(session)
- if xcos_file_id < 0 or xcos_file_id >= len(diagrams):
+ if xcos_file_id not in diagrams:
logger.warning('id %s not in diagrams', xcos_file_id)
return None
@@ -1118,14 +1423,15 @@ def get_diagram(session, xcos_file_id, remove=False):
return diagram
-def add_diagram(session):
+def add_diagram(session, task):
(diagrams, scripts, __, __, __, sessiondir, diagramlock) = init_session(session)
with diagramlock:
diagram = Diagram()
diagram.diagram_id = str(len(diagrams))
diagram.sessiondir = sessiondir
- diagrams.append(diagram)
+ # diagrams.append(diagram)
+ diagrams[task.task_id] = diagram
return (diagram, scripts, sessiondir)
@@ -1316,10 +1622,10 @@ def clean_text_2(s, forindex):
return s
-def kill_scilab(diagram=None, session=None):
+def kill_scilab(diagram=None, session=None, task=None):
'''Define function to kill scilab(if still running) and remove files'''
if diagram is None:
- diagram = get_diagram(session, get_request_id(), True)
+ diagram = get_diagram(session, task, True)
if diagram is None:
logger.warning('no diagram')
diff --git a/blocks/simulationAPI/tasks.py b/blocks/simulationAPI/tasks.py
index f41ec7de..7360fcc6 100644
--- a/blocks/simulationAPI/tasks.py
+++ b/blocks/simulationAPI/tasks.py
@@ -33,8 +33,8 @@ def process_task(self, task_id):
lock = acquire_lock(session_id) # Prevent multiple runs per session
try:
- logger.info("Processing %s %s %s",
- task_id, task.file.path, task.session.app_name)
+ logger.info("Processing %s %s %s %s",
+ task_id, task.file.path, task.session.app_name, task.workspace_file)
update_task_status(task_id, 'STARTED',
meta={'current_process': 'Started Processing File'})
@@ -44,7 +44,7 @@ def process_task(self, task_id):
state = 'STREAMING'
current_process = 'Processed Script, Streaming Output'
else:
- output = ExecXml(task, self.name)
+ output = ExecXml(task, self.name, task.workspace_file)
if output == "Streaming":
state = 'STREAMING'
current_process = 'Processed Xml, Streaming Output'
@@ -73,4 +73,6 @@ def process_task(self, task_id):
def process_task_script(task_id):
task = Task.objects.get(task_id=task_id)
session = task.session
- return getscriptoutput(session, task)
+ result = getscriptoutput(session, task)
+ update_task_status(task_id, 'SUCCESS', meta=result)
+ return result
diff --git a/blocks/simulationAPI/views.py b/blocks/simulationAPI/views.py
index 09541c75..03494c46 100644
--- a/blocks/simulationAPI/views.py
+++ b/blocks/simulationAPI/views.py
@@ -17,7 +17,7 @@ from simulationAPI.models import Task, Session
from simulationAPI.negotiation import IgnoreClientContentNegotiation
from simulationAPI.serializers import TaskSerializer
from simulationAPI.tasks import process_task, process_task_script
-from simulationAPI.helpers.ngspice_helper import CreateXcos
+from simulationAPI.helpers.ngspice_helper import CreateXcos, update_task_status
@@ -64,11 +64,26 @@ class XmlUploader(APIView):
serializer = TaskSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
- serializer.save()
+ task = serializer.save()
+
+ task_type = request.data.get('type')
+ script_task_id = request.data.get('script_task_id')
+
+ if task_type == 'XCOS' and script_task_id:
+ try:
+ script_task = Task.objects.get(task_id=script_task_id, type='SCRIPT')
+ if script_task.workspace_file:
+ task.workspace_file = script_task.workspace_file
+ task.save()
+ logger.info(f'Copied workspace file from script task {script_task_id} to xcos task {task.task_id}')
+ else:
+ logger.warning(f'Script task {script_task_id} does not have a workspace file')
+ except Task.DoesNotExist:
+ logger.warning(f'Script task {script_task_id} not found')
+ # serializer.save()
task_id = serializer.data['task_id']
celery_task = process_task.apply_async(
kwargs={'task_id': str(task_id)}, task_id=str(task_id))
- # celery_task = process_task.delay(str(task_id))
response_data = {
'state': celery_task.state,
'details': serializer.data,
@@ -350,6 +365,7 @@ class StreamView(APIView):
else:
logger.info('lines = %s, log size = %s', lineno, log_size)
+ update_task_status(task_id, 'SUCCESS')
# Notify Client
yield "event: DONE\ndata: None\n\n"
@@ -364,6 +380,7 @@ class GetScriptOutputView(APIView):
try:
celery_task = process_task_script.apply_async(kwargs={'task_id': str(task_id)}, task_id=str(uuid.uuid4()))
result = celery_task.get(timeout=30)
+ update_task_status(celery_task.id, 'SUCCESS', meta=result)
print("RESULT:", result)
return Response(result, status=status.HTTP_200_OK)
except Exception as e: