I need to separate the text to pass the information to 3 different tags. string length will be different so i can’t just use a split or substring to separated.
What i’m trying to achieve with this is to access any in a Siemens PLC, for example a Technician would type in the input boxes “M500.0” then I need to get “M”,“500”,“0”, all three separated, which i could do if the length of the string was always the same, but they can also type “M1000.7” or “MW300” or “PIW346” so here is where i run into my problem. As I can’t use the same code for all this variations. ideally what i would be looking for, would be something that would get the index of the last letter or the first number and do the first split there , then use the “.” for the other split, if there is a “.” , in the case of MW and PIW I don’t even need to split a second time because there is not bit value.
This is my ignition Screen.
Originally I had design this in a Weintek Hmi using a Dropdown to select the Data type (M, MW, I, Q,PIW and so on) then use two different input box to type the rest. i pass this to a S7 STL code and from there i read the status of the selected address and give the Status back. this way Maintenance tech can troubleshoot without the need of going into the PLC. With Ignition I thought it would be better to do Multiple status check as the same time for different addresses. that way they can probably check the status of a full network by just typing the address that they have on the printed program, this is a much needed solution for our company.
Using the dropdown and two different input boxes does not make much sense as i can have them just type the address in an input and i separate into 3. well at least that is what I wanted to do. but so far no luck.
so if anyone can help it would be really appreciated. and i would gladly provide the STL code if someone wants it for them. this a anypointer STL code to get any address in the PLC without the need of opening a DB or anything. and it would work on any program as long as the FC is called.
Another option is to use regex and split. This is a bit more verbose than it can be but much more readable for it.
import re
testS = 'M1000.7'
letterMatch = r'(\D*\B)'
numberMatch = r'((?:(?!.).)*\d+)'
# Find all letters from start of string until the first digit. Returns an array of one in this case
letters = re.findall(letterMatch,testS)[0]
# First group captured is all numbers after the letters but before the dot
numbers = re.findall(numberMatch,testS)[0]
# If there is a dot, grabs everything after it
bit = ''
if '.' in testS:
bit = testS.split('.')[1]
print letters # prints M
print numbers # prints 1000
# bit evaluates to false if it is empty
if bit: print bit # prints 7
All three variables will be strings just in case that matters but they will be easily castable
Different regex approach (I would also recommend regex for this): ^([A-Z]+)(\d+)((?:\.)\d+)?
Group 1 is the data type, group 2 is the address, group 3 (if present) is the bit address.