Alarm tags - bits

[quote=“zxcslo”]@JordanCClark
When I try to run your code I get this error (I have your PV+ Alarms.xml in root of my C:\ drive):
[/quote]

It looks like it’s not finding SAXParser. Bummer.

I seem to remember something about saxparser deprecation between Java 1.6 and 1.7 (I’m still using 1.6 here in my production environment.). I’ll check it out.

Secret option B would be to do it all through text manipulation. It was just that using ElementTree made it easier for my poor brain… :mrgreen:

OK, researching let me find this jython issue: http://bugs.jython.org/issue1537

But, looking at the location of the C:\Users[i][username][/i]\AppData\LocalLow\Sun\Java\Deployment\cache\FPMI\script_lib2\Lib\xml\parsers\expat.py file I see that the fix is there.

If you could do me a favor and run this script in the Script Playground:

[code]try:
import org.python.apache.xerces.parsers.SAXParser as parser1
print “Successfully imported org.python.apache.xerces.parsers.SAXParser”
except:
print “Failed to import org.python.apache.xerces.parsers.SAXParser”

try:
import org.apache.xerces.parsers.SAXParser as parser2
print “Successfully imported org.apache.xerces.parsers.SAXParser”
except:
print “Failed to import org.apache.xerces.parsers.SAXParser”[/code]

I’m looking to see if the actual imports are working correctly. (It only needs to be able to import one of them).

@JordanCClark

I’ve tried your two imports: the first one is success, the second one is failed.
[attachment=0]Capture.PNG[/attachment]

That’s what I get, as well. I’m thinking that’s a good thing!

So, my next thought is that perhaps one of the ClassLoaders is a bit off. Maybe a fresh install of the designer and re-downloading the local libraries is on order.

To do that, first uninstall whatever local webstart apps you may have:

javaws.exe -uninstall

Next, delete whatever is in the FPMI cache. I don’t know if it’s absolutely necessary, but it won’t hurt anything. Java and Ignition will replace anything that you take out.
Go to C:\Users[username]\AppData\LocalLow\Sun\Java\Deployment\cache (in your case it’ll be in C:\Users\zxc\AppData\LocalLow\Sun\Java\Deployment\cache) and delete (or rename) the FPMI folder.

Launch the designer and open a project.

Try the script again.

After that, I’m out of ideas. Anyone else wanna jump in?

@JordanCCLark

I deleted the cache and now it’s working. :slight_smile: :thumb_left:

Now I (we) need that for .csv file.
I export my Symbol table to Excel and save it to .csv file.
Could you rewrite your script so that input file is .csv and output is Ignition xml? :prayer:

OK, let me see if I have this right… It’s because I’m not a Siemens guy. :laughing:

You can export from the Siemens software directly as an Excel file? If so, are there any other formats available? I ask this so that we can perhaps skip a step.

EDIT: On second thought, Let’s skip over that for now. If you give me a csv file with a bit of an explanation of your columns, I can take it from there. After we get that process working, we can look at other methods. :wink:

Also it’s okay if it’s a full-column export. Meaning, you don’t have to remove any columns, just let me know which ones are in use. And also save an extra step. :slight_smile:

Thats not exactly true. I’m also using Calc to create tags from external sources. I usually create a template tag in Ignition, export as XML and then use Calc with some cell formulas and copy/paste or autofill to create additional tags. Then i reimport the new tags into Ignition. That’s also the reason for the seperate alarms table, you can simply copy/paste your alarm texts there.
That’s maybe a bit more work than you want to do, but it works perfectly for me and my co-worker which know how to use Excel/Calc but not how to write scripts in Ignition.
I attached a sample table to this post (Just delete the ‘.zip’ from the filename, the forum software does not accept .ods files).

[quote=“JordanCClark”]OK, let me see if I have this right… It’s because I’m not a Siemens guy. :laughing:

You can export from the Siemens software directly as an Excel file? If so, are there any other formats available? I ask this so that we can perhaps skip a step.[/quote]
No. Siemens software support .asc (ASCII), .seq (for older Simatic systems) and .dif (Data Interchange Format). DIF file is the one, which can be normally open in Excel, manipulated and then saved as csv.
ASC file is normal text file (you can edit it in Notepad), but it’ll need some processing before converting it to Ignition xml.

I attached .csv and .asc (remove .zip) file and Ignition tags export/import .xml file, and .dif file (remove .zip) which can be opened in Excel and manipulated.
I opened .dif in Excel, change the columns (M 100.0 -> MX100.0, M 100.0 -> M100_0) and save it as .csv.
In .csv:
First column (MX100.0) is tag format for Ignition. Bit tags in Ignition have X.
Second column (M100_0) is tag name for Ignition (Hence _, because Ignition won’t allow dots in tag names).
Third column is tag type; BOOL in Siemens is DataType 6 in Ignition
Fourth column is Alarm text in Siemens, and Alarm name in Ignition.

Thats not exactly true. I’m also using Calc to create tags from external sources. I usually create a template tag in Ignition, export as XML and then use Calc with some cell formulas and copy/paste or autofill to create additional tags. Then i reimport the new tags into Ignition. That’s also the reason for the seperate alarms table, you can simply copy/paste your alarm texts there.
That’s maybe a bit more work than you want to do, but it works perfectly for me and my co-worker which know how to use Excel/Calc but not how to write scripts in Ignition.
I attached a sample table to this post (Just delete the ‘.zip’ from the filename, the forum software does not accept .ods files).[/quote]
Yes, I understand. I tried your filters in OpenOffice and I might use that.
But, I see in your latest attachment that you have defined MW as tags, and then in alarms sheet you used bitPosition (0-15).
How is that?

[quote]But, I see in your latest attachment that you have defined MW as tags, and then in alarms sheet you used bitPosition (0-15).
How is that?[/quote]
I find it easier to use a word tag and define 16 alarms for the single bits. If i remember right, this option is new in 7.6.

[quote=“zxcslo”]
No. Siemens software support .asc (ASCII), .seq (for older Simatic systems) and .dif (Data Interchange Format). DIF file is the one, which can be normally open in Excel, manipulated and then saved as csv.
ASC file is normal text file (you can edit it in Notepad), but it’ll need some processing before converting it to Ignition xml.

I attached .csv and .asc (remove .zip) file and Ignition tags export/import .xml file, and .dif file (remove .zip) which can be opened in Excel and manipulated.
I opened .dif in Excel, change the columns (M 100.0 -> MX100.0, M 100.0 -> M100_0) and save it as .csv.
In .csv:
First column (MX100.0) is tag format for Ignition. Bit tags in Ignition have X.
Second column (M100_0) is tag name for Ignition (Hence _, because Ignition won’t allow dots in tag names).
Third column is tag type; BOOL in Siemens is DataType 6 in Ignition
Fourth column is Alarm text in Siemens, and Alarm name in Ignition.[/quote]
Wow! My cup runneth over! Thanks!

One more question. I see in your SQLTag file that you have an Alarm setpoint of 10. Is that deliberate? Booleans, as you know, won’t get there. I can stick it in as a 10, I just wanted to be sure that’s what you wanted. :slight_smile:

[quote=“JordanCClark”][quote=“zxcslo”]
No. Siemens software support .asc (ASCII), .seq (for older Simatic systems) and .dif (Data Interchange Format). DIF file is the one, which can be normally open in Excel, manipulated and then saved as csv.
ASC file is normal text file (you can edit it in Notepad), but it’ll need some processing before converting it to Ignition xml.

I attached .csv and .asc (remove .zip) file and Ignition tags export/import .xml file, and .dif file (remove .zip) which can be opened in Excel and manipulated.
I opened .dif in Excel, change the columns (M 100.0 -> MX100.0, M 100.0 -> M100_0) and save it as .csv.
In .csv:
First column (MX100.0) is tag format for Ignition. Bit tags in Ignition have X.
Second column (M100_0) is tag name for Ignition (Hence _, because Ignition won’t allow dots in tag names).
Third column is tag type; BOOL in Siemens is DataType 6 in Ignition
Fourth column is Alarm text in Siemens, and Alarm name in Ignition.[/quote]
Wow! My cup runneth over! Thanks!

One more question. I see in your SQLTag file that you have an Alarm setpoint of 10. Is that deliberate? Booleans, as you know, won’t get there. I can stick it in as a 10, I just wanted to be sure that’s what you wanted. :slight_smile:[/quote]
No, I think that’s the bug in Ignition tag export/import routine:
I’m from Europe (Slovenia) and we have a comma (,) for decimal separator and dot (.) for thousands. (set in Windows Regional settings)
When you do tag export, there is always 1.0 (instead of 1,0) in xml file. When you do import the same file, you get 10. If the change is made by hand in xml file from 1.0 to 1,0 it’ll import correctly.
So I guess export doesn’t care about regional settings, but import does.
I just give you this file without corrections. There must be Alarm setpoint at 1.0 (1,0).

[quote=“chi”][quote]But, I see in your latest attachment that you have defined MW as tags, and then in alarms sheet you used bitPosition (0-15).
How is that?[/quote]
I find it easier to use a word tag and define 16 alarms for the single bits. If i remember right, this option is new in 7.6.[/quote]
Wau… I didn’t know that… :blush:
I’ve looked again and now I found it.
The last project I have, I made it with v7.6.6 and I didn’t know about this, so I defined all alarms tags as BOOLEAN… :slight_smile:
Oh well…

Here’s the first crack at making an XML file from a Siemens .asc file. Should be locale agnostic, meaning it should pop in the correct decimal point for your locale. At least, that was the plan! :mrgreen:

[code]import xml.etree.ElementTree as ET
import locale

decimalPoint=locale.localeconv()[‘decimal_point’]
thousandsSep=locale.localeconv()[‘thousands_sep’]

OPCServer=‘Ignition OPC-UA Server’
deviceName=’[s7_300]’
alarmFolderName=‘Napake’

pathIn=system.file.openFile(‘asc’)

if pathIn != None:
txt = system.gui.inputBox(“OPC Server:”, OPCServer)
if txt != None:
OPCServer=txt
txt = system.gui.inputBox(“Device Name:”, deviceName)
if txt != None:
deviceName=txt
txt = system.gui.inputBox(“Alarm Folder Name:”, alarmFolderName)
if txt != None:
alarmFolderName=txt
fileIn=open(pathIn)

#Root 
writeTree=ET.Element('Tags')
#Alarm Folder
alarmFolder=ET.SubElement(writeTree, 'Tag', {'name':alarmFolderName, 'path':'', 'type':'Folder'})

for line in fileIn:
    bit=line[line.find(',')+1:25].strip().replace(' ','X')
    tagname=bit.replace('X','').replace('.','_')
    desc=line[50:].strip()+' ('+bit.replace('X','')+')'

    tag=ET.SubElement(writeTree, 'Tag', {'name':tagname, 'path':alarmFolderName, 'type':'OPC'})
    property=ET.SubElement(tag, 'Property', {'name':'Value'})
    property.text='false'
    property=ET.SubElement(tag, 'Property', {'name':'DataType'})
    property.text='6'
    property=ET.SubElement(tag, 'Property', {'name':'OPCServer'})
    property.text=OPCServer
    property=ET.SubElement(tag, 'Property', {'name':'OPCItemPath'})
    property.text=deviceName+bit

    #Set up alarm properties 
    alarms=ET.SubElement(tag, 'Alarms')
    alarm=ET.SubElement(alarms, 'Alarm',{'name':desc})
    property=ET.SubElement(alarm, 'Property', {'name':'priority'})
    property.text='1'
    property=ET.SubElement(alarm, 'Property', {'name':'setpointA'})
    property.text='1'+decimalPoint+'0'
    property=ET.SubElement(alarm, 'Property', {'name':'ackMode'})
    property.text='1'

fileIn.close()

path = system.file.saveFile(deviceName.replace('[','').replace(']','')+".xml")
if path != None:
    rough_string = ET.tostring(writeTree, 'utf-8')
    system.file.writeFile(path,rough_string)

[/code]

Here’s one that may use bit position alarms. I say may, because some of the Unicode characters seem to get hosed going into and out of the dictionaries. It may be a locale thing, so your mileage may vary… hopefully better than mine! :unamused:

Really, I’m not in the habit of handing out stuff that doesn’t work, but it will work with ASCII. It’s Unicode manipulation that seems to be my current nemesis. :laughing:

[code]import xml.etree.ElementTree as ET
import locale

locale.setlocale(locale.LC_ALL, ‘sl-si’)

pathIn=system.file.openFile(‘asc’)

if pathIn != None:

txt = system.gui.inputBox(“OPC Server:”, OPCServer)

if txt != None:

OPCServer=txt

txt = system.gui.inputBox(“Device Name:”, deviceName)

if txt != None:

deviceName=txt

txt = system.gui.inputBox(“Alarm Folder Name:”, alarmFolderName)

if txt != None:

alarmFolderName=txt

fileIn=open(pathIn)

AlarmDict={}
for line in fileIn:
    ElementDict={}
    bit=line[line.find(',')+1:25].strip().replace(' ','X')
    word=bit[:bit.find('.')].replace('X','W')
    tagname=bit.replace('X','').replace('.','_')
    desc=line[50:].strip()+' ('+bit.replace('X','')+')'
    if word not in AlarmDict:
        AlarmDict[word]={}
    if bit not in AlarmDict[word]:
        AlarmDict[word][bit]=[tagname, desc]
fileIn.close()

#Root
writeTree=ET.Element('Tags')
#Alarm Folder
alarmFolder=ET.SubElement(writeTree, 'Tag', {'name':alarmFolderName, 'path':'', 'type':'Folder'})


for wordKey in AlarmDict.keys():
    tag=ET.SubElement(writeTree, 'Tag', {'name':wordKey, 'path':alarmFolderName, 'type':'OPC'})
    property=ET.SubElement(tag, 'Property', {'name':'Value'})
    property.text='false'
    property=ET.SubElement(tag, 'Property', {'name':'DataType'})
    property.text='1'
    property=ET.SubElement(tag, 'Property', {'name':'OPCServer'})
    property.text=OPCServer
    property=ET.SubElement(tag, 'Property', {'name':'OPCItemPath'})
    property.text=deviceName+bit
    for bitKey in AlarmDict[wordKey].keys():
        #Set up alarm properties
        bitPosition=bitKey[bitKey.find('.')+1:]
        desc=AlarmDict[word][bit][1]
        alarms=ET.SubElement(tag, 'Alarms')
        print desc
        alarm=ET.SubElement(alarms, 'Alarm',{'name': desc})
        property=ET.SubElement(alarm, 'Property', {'name':'priority'})
        property.text='1'
        property=ET.SubElement(alarm, 'Property', {'name':'setpointA'})
        property.text='1'+decimalPoint+'0'
        property=ET.SubElement(alarm, 'Property', {'name':'ackMode'})
        property.text='1'
        property=ET.SubElement(alarm, 'Property', {'name':'bitPosition'})
        property.text=bitPosition
         

path = system.file.saveFile(deviceName.replace('[','').replace(']','')+".xml")
if path != None:
    rough_string = ET.tostring(writeTree, 'utf-8')
    system.file.writeFile(path,rough_string)[/code]

@JordanCClark
Thank you for your effort. :prayer:
Let’s talk about your first script:
When I run it, I get the xml file. When I try to import that xml file, I get error:
[attachment=2]Capture2.PNG[/attachment]
The other thing is about locale decimal point and thousand separator:
I’ve put in the script:

[code]import xml.etree.ElementTree as ET
import locale

decimalPoint=locale.localeconv()[‘decimal_point’]
thousandsSep=locale.localeconv()[‘thousands_sep’]
print “Decimal point :” + decimalPoint
print "Thousand sep: " + thousandsSep
#print locale.getdefaultlocale()
print locale.localeconv()
[/code]
And this is what I get in output console:
[attachment=1]Capture3.PNG[/attachment]
In Regional settings in Windows decimal point is set to comma (,) and thousand separator to dot (.).
I guess the locale function behave differently on Windows OS than on Linux or else… :slight_smile:

Next thing:
When I add locale.setlocale(locale.LC_ALL, ‘sl-si’):

[code]import xml.etree.ElementTree as ET
import locale

decimalPoint=locale.localeconv()[‘decimal_point’]
thousandsSep=locale.localeconv()[‘thousands_sep’]
print “Decimal point :” + decimalPoint
print "Thousand sep: " + thousandsSep
#print locale.getdefaultlocale()
print locale.localeconv()

locale.setlocale(locale.LC_ALL, ‘sl-si’)
#print locale.localeconv()

OPCServer=‘Ignition OPC-UA Server’
deviceName=’[s7_300]’
alarmFolderName=‘Napake2’

pathIn=system.file.openFile(‘asc’)[/code]
I get this error:
[attachment=0]Capture4.PNG[/attachment]

EDIT:
The first error (invalid byte…) is gone if I remove utf-8 from ET.tostring:

if path != None: #rough_string = ET.tostring(writeTree, 'utf-8') rough_string = ET.tostring(writeTree) #print rough_string system.file.writeFile(path,rough_string)
Now I can import xml file and I get all the tags, but some slovenian characters are not right.
I guess it has something to do with encoding of the asc file and/or the Ignition/Java.
In slovenian language we have a few special characters, like čćžšđ ČĆŽĐŠ, and no mater what I try, I can’t get this characters into xml file…
I have encoded .asc file to utf-8, unicode, ansi (default),… but nothing…

EDIT EDIT:
I’ve tried all this in v7.7.0-beta3 (b2014061610).
It’s the same… the only thing that’s different is that now, when you import tag xml and setpointA is 1,0 (with comma), you’ll get 10 in Ignition Tag Editor. So it must be 1.0 (with dot). It reverse from v7.6. Now it doesn’t care at all, what is local decimal separator set in Windows Regional settings.

Thanks for the update. Oddly enough, that first script worked ok for me, special characters and all. :open_mouth:

Yeah, those special characters are giving me fits! And trying to set a locale is not much better. I’ll take a closer look at Java’s classes. Maybe there something in there that will work better for locales. :imp:

If you still have trouble with the decimals and thousands separator, you can hard code the values. In my case it would look like:

EDIT: removed bad code... really bad code... See later post.

On the bright side, we have a basic framework that does what it’s supposed to do. Now, if we can get rid of the ‘undocumented features’, we’ll have something special!

To the general public: I don’t think zxcslo or my feelings will get hurt if someone else jumps in. There’s plenty of room in the pool, and the water’s nice! :smiley: I’ve got about one more day I can put toward this before vacation. After that, it’ll be about a week.

When I put:

decimalPoint=locale.localeconv()['.'] thousandsSep=locale.localeconv()[',']
I get this: :scratch:
[attachment=0]Capture1.PNG[/attachment]

Sorry. It was early when I wrote that. :blush:

decimalPoint='.' thousandsSep=','

After a long time, I return to this ‘problem’, because now I was really need to import over 3000 tags from Siemens Simatic PLC to Ignition.
With the help of others, participating in this thread :prayer: I find 3 ways to do it:

  1. This is the longest way (much hand work involved and I wrote a small program in VS2010, because I’m more of Microsoft guy for most of my life :blush: )
  2. Second way will convert exported ascii txt (.asc) file from Simatic Manager to Ignition XML, with the help of Python (Jyton) script from inside the Ignition designer (Script playground), to Bit (Boolean) Tags with alarms defined for each tag
  3. Third way will convert exported ascii txt file (.asc) from Simatic Manager to Ignition XML, with the help of Python (Jyton) script from inside the Ignition designer (Script playground), to Byte Tags with alarms defined for each bit in that Byte tags.

I’ve attached all three files (one .zip and two txt files).
Feel free to look, try, adapt and please, comment on them. :thumb_left:
STEP7 alarm taqs to Ignition ByteTags 3way.txt (4.29 KB)
STEP7 alarm taqs to Ignition BitTags 2way.txt (3.44 KB)
STEP7 alarm taqs to Ignition_1way.zip (131 KB)

1 Like