CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Mon Aug 26, 2019 4:53 am

All times are UTC+01:00




Post new topic  Reply to topic  [ 8 posts ] 
Author Message
 Post subject: XML Parsing
PostPosted: Wed May 16, 2012 1:13 pm 
Offline

Joined: Tue Apr 13, 2010 1:59 pm
Posts: 21
Hello,

I am trying to create a script where I can build different versions of my applications by toggling pragma variables declaration.
I understand that the only way to change the code at this point would be:
1. Export the gvl as XML
2. Modify the XML
3. Import back the modified XML

My problem is: how can I modify the XML? Ironpython has no implementation of pyexpat.py, so nothing like dom, minodom or etree will work. I could use some .net constructs, but trying to import CLR gives me an error "Access to module clr not permitted".

Why restrict access to CLR......?


Top
   
 Post subject: Re: XML Parsing
PostPosted: Wed May 16, 2012 2:04 pm 
Offline
Frequent User
Frequent User
User avatar

Joined: Fri Mar 18, 2011 4:12 pm
Posts: 266
Hi, Francois,

francois wrote:
I am trying to create a script where I can build different versions of my applications by toggling pragma variables declaration.
I understand that the only way to change the code at this point would be:
1. Export the gvl as XML
2. Modify the XML
3. Import back the modified XML

My problem is: how can I modify the XML? Ironpython has no implementation of pyexpat.py, so nothing like dom, minodom or etree will work.

As soon as IronPython has a working XML implementation, we intend to ship it with CoDeSys. So the "best" way is to contribute a working XML implementation to the IronPython project. This gives a lot of positive karma. :wink:

francois wrote:
I could use some .net constructs, but trying to import CLR gives me an error "Access to module clr not permitted".

Since V3.5, the System.Xml assembly is available for IronPython scripts:
Code:
import System
doc = System.Xml.XmlDocument()


For older CoDeSys versions, the possible workarounds include:
[list=]
[*]You can execute external commands (including cPython scripts) to process the XML for you.
[*]Use Pyro or some other remote call tools to call a cPython "server" processing your requests
[*]Use the ctypes module to import some native library which does the processing.
[*]Modify the XML using simple text manipulation (this works for some simple cases.)
[/list]

francois wrote:
Why restrict access to CLR......?

For several (mostly political) reasons, the ScriptEngine is "sandboxed" a little bit. If there are convincing usecases for access to the clr module, we might remove or rework that restriction, or expose the required functionality in a different way. Note that Automation Platform plugins are free to lift this restriction when they instantiate Script Executors for their own purposes.

_________________
Check out the CODESYS store: http://store.codesys.com/

CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions


Top
   
 Post subject: Re: XML Parsing
PostPosted: Thu May 17, 2012 12:24 pm 
Offline

Joined: Tue Apr 13, 2010 1:59 pm
Posts: 21
Thanks for your answer!

With the System.Xml assemblies, it means minidom can be used with the following manipulations:

1.Take the CPython expatbuilder.py and copy it to the xml/dom scripts folder
2. With a slight modification to FePy's pyexpat.py , rename it to expat.py and copy it to xml/parsers scripts folder
Code:
#import clr
#clr.AddReference("System.Xml")

This enables the standard python xml implmentations!

Regards,
Francois


Top
   
 Post subject: Re: XML Parsing
PostPosted: Fri May 18, 2012 7:46 am 
Offline
Frequent User
Frequent User
User avatar

Joined: Fri Mar 18, 2011 4:12 pm
Posts: 266
Hi, Francois,

francois wrote:
With the System.Xml assemblies, it means minidom can be used with the following manipulations:

1.Take the CPython expatbuilder.py and copy it to the xml/dom scripts folder
2. With a slight modification to FePy's pyexpat.py , rename it to expat.py and copy it to xml/parsers scripts folder
Code:
#import clr
#clr.AddReference("System.Xml")

This enables the standard python xml implementations!


This is great news, thanks!

I just tested it, and it seems to work. I'll try to get this into V3.5 SP2. (It is to late for 3.5 SP1, code close was more than 1 month ago...)

The last time when I checked pyexpat.py, it did not really work well - even using minidom did not work. (And I tested it in plain IronPython without CoDeSys.)

_________________
Check out the CODESYS store: http://store.codesys.com/

CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions


Top
   
 Post subject: Re: XML Parsing
PostPosted: Thu May 24, 2012 7:38 am 
Offline
Frequent User
Frequent User
User avatar

Joined: Fri Mar 18, 2011 4:12 pm
Posts: 266
Hi,

Just as an Update on this issue: Today I got the mail that IronPython upstream is about to fix this issue: http://ironpython.codeplex.com/workitem/20023

_________________
Check out the CODESYS store: http://store.codesys.com/

CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions


Top
   
PostPosted: Mon Jul 02, 2012 12:53 pm 
Offline
Frequent User
Frequent User
User avatar

Joined: Fri Mar 18, 2011 4:12 pm
Posts: 266
Hi,

Just another update: In our Jira-Database, we opened issue CDS-29369 to rework the sandboxing so "import clr" is allowed.

If you need "import clr" functionality, it is best to use your official support contact to get your company added to this jira entry.

HTH,
Markus

_________________
Check out the CODESYS store: http://store.codesys.com/

CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions


Top
   
 Post subject: Re: XML Parsing
PostPosted: Wed Oct 24, 2012 5:34 pm 
Offline
Frequent User
Frequent User
User avatar

Joined: Fri Mar 18, 2011 4:12 pm
Posts: 266
Hi,

Good news: the change which allows "import clr" did just slip into V3.5 SP2 (which is scheduled for december).

There are some filters in the AddReferenceXXX()-Calls which prohibit access to CODESYS internal APIs, but all other .NET Assemblies are freely accessible.

HTH,
Markus

_________________
Check out the CODESYS store: http://store.codesys.com/

CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions


Top
   
 Post subject: Re: XML Parsing
PostPosted: Thu Oct 25, 2012 8:45 am 
Offline

Joined: Wed Jul 18, 2012 11:42 am
Posts: 15
Hi,

As a solution to this I will show You script that I did create and it is used to module parameter changing. Basically it export module info to xml file, modify line with parameters and import this file again.

Code:
from __future__ import print_function
from ConfigParser import SafeConfigParser

import os, ctypes, sys

PATH = r"C:\\TestStand\\Systemtest\\Libs\\CoDeSys\\"
BUS == 'Profinet'
COUPLER = 'Profinet_Coupler_Name'
MODULE = 'Analog_Module_Name'
IN_FILE = PATH + "export.xml"
OUT_FILE = PATH + "import.xml"
TCMASTER = PATH + "tcMaster.txt"
Line = 1

# create the export reporter
class Reporter(ExportReporter):
   def error(self, message):
      system.write_message(Severity.Error, message)

   def warning(self, message):
      system.write_message(Severity.Warning, message)

   def resolve_conflict(self, obj):
      return ConflictResolve.Copy

   def nonexportable(self):
      print("non exportable")

   @property
   def aborting(self):
      return False

# create the exporter instance.
exp_reporter = Reporter()
      
# create the import reporter
class Reporter(ImportReporter):
   def error(self, message):
      system.write_message(Severity.Error, message)

   def warning(self, message):
      system.write_message(Severity.Warning, message)

   def resolve_conflict(self, obj):
      return ConflictResolve.Copy

   def added(self, obj):
      print("added: ", obj)

   def replaced(self, obj):
      print("replaced: ", obj)

   def skipped(self, obj):
      print("skipped: ", obj)

   @property
   def aborting(self):
      return False

# create the importer instance.
imp_reporter = Reporter()

def subStrXml():
   lRetVal=0
   if BUS == 'Profinet':
      PRETAG = '<Element name="RecordData">'
      POSTTAG = '</Element>'
   else: #'Profibus'
      PRETAG = '<Element name="userParameter">'
      POSTTAG = '</Element>'

   IN_BLOCK = False

   pos1 = -42
   pos2 = -42
   OUT = "";

   fhIn = open(IN_FILE,"r")
   fhOut = open(OUT_FILE,"w")

   TCM = SafeConfigParser()
   TCM.read(TCMASTER)

   print('Build: Text: Modifying file...')

   # replace module parameters in xml file
   for line in fhIn:   
      pos1 = line.find(PRETAG) # look for begin
      pos2Offset = 0
      if pos1 >= 0 :
         pos2Offset = pos1
         pos2 = line.find(POSTTAG, pos2Offset) # look for end, maybe same line

      if pos1 > 0 :
         IN_BLOCK = True
         OUT += line[0:pos1+len(PRETAG)]
         try:
            OUT += TCM.get('DEFAULT', "Line"+INDEX).split(';')[int(SUBIDX)]
         except:
            print('Error: tcMaster - TC not found or index out of bound')
            lRetVal=1
            

      if pos2 > 0 and IN_BLOCK == True :
         IN_BLOCK = False
         OUT += line[pos2:]

      if ( pos1 < 0 or pos2 < 0 ) and not IN_BLOCK:
         OUT += line

      pos1 = -42
      pos2 = -42

   fhOut.write(OUT)

   fhIn.close()
   fhOut.close()
   return lRetVal

if BUS == 'Profibus':
   project = PATH + "Projekt\SysTS_FBC-PB-DP\\SysTS_FBC-PB-DP.project"
   COUPLER = 'UR20_FBC_PB_DP'
elif BUS == 'Profinet':
   project = PATH + "Projekt\SysTS_FBC-PN\\SysTS_FBC-PN.project"
   COUPLER = 'UR20_FBC_PN_IRT_Profinet_Device'
else:
   print('Build: Error: Bus ' + BUS + ' not found')
   flag = 9
   globData.write(globData.compile())
   system.delay(3000)
   system.exit()

print('Build: Text: UUT Connection Type: ' + BUS)



# main program

# export module to xml
obj = proj.find(MODULE, True)
         
if (len(obj) > 0):
   obj[0].export_xml(exp_reporter, IN_FILE, True)
            
   # change module parameters
   returnValue = subStrXml()
         
   if (returnValue != 0):
      print('Error')
         
   else:
      dev = proj.find(COUPLER, True)
            
      # import module, move to correct position and run application
      module_index = obj[0].index
      obj[0].remove()
      dev[0].import_xml(imp_reporter, OUT_FILE)
      obj = proj.find(MODULE, True)
      obj[0].move(dev[0], module_index)
      os.remove(OUT_FILE)
               
else:
   print('Build: Error: Object not found')




And the tcMaster file kooks like this:

[DEFAULT]
Line1=[16#0A,16#00,16#04,16#01,16#0F,16#00,16#09,16#09,16#09,16#09]
Line2=[16#0A,16#00,16#04,16#01,16#0F,16#00,16#0A,16#0A,16#0A,16#0A]

It is easy to modify this to Your needs.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 8 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited