def auto_select_operator_interaction(msg_nr, action):
if action == 2: # Outgoing alarm
# If action was selected, then unselect
if msg_nr == system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition"):
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", 0)
# Shift all active alarms from the selected one
for index in range(20):
if system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index)) == msg_nr:
temp_index = index - 1
while temp_index < 20:
temp_index += 1
index_van = temp_index + 1
system.tag.writeBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(temp_index),
system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index_van)))
# Select new one
if system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition") == 0 and system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]") > 0:
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]"))
elif action == 1: # Incoming alarm
for index in range(20):
if system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index)) == 0:
system.tag.writeBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index), msg_nr)
# Select new one
if system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition") == 0:
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]"))
else: # Loop in alarm
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", msg_nr)
what the result should be after this is being executed is that the first number in my array of the tag 'L4_Active_Operator_Msg' should be 5. But instead it stays 0.
The function doesn't return anything so my return in the Console screen is empty.
It is not giving an error that something is wrong with the function so I don't know why it is not working.
system.tag.read* functions return a list of qualified values. Its return will NEVER be equal to 0.
Now, another thing to note: avoid running multiple calls to the tag read and write functions. Build the data first, then pass everything in just one call. Or as few calls as possible.
It will also probably make the logic easier to follow.
Yes, we covered that yesterday where you were running 48 × readBlocking which will run one after another with each waiting until it is finished before going on to the next one. Read them all at once if at all possible. (There will be a maximum limit - but it will be large.)
I'm not sure this does what it's supposed to do.
Can you explain in details what you want to happen, maybe with a couple of examples ?
Can you explain WHY you're moving things around ?
I rewrote it to read and write just once, keeping (I believe) the same logic:
def auto_select_operator_interaction(msg_nr, action):
op_index_path = "[Test SCADA Ignition]OperatorIndexIgnition"
op_msg_path = "[Test SCADA Ignition]L4_Active_Operator_Msg"
op_index, op_msg = [qval.value for qval in system.tag.readBlocking([op_index_path, op_msg_path])]
if action == 2: # Outgoing alarm
# If action was selected, then unselect
if msg_nr == op_index:
op_index = 0
# Shift all active alarms from the selected one
for index in xrange(20):
if op_msg[index] == msg_nr:
temp_index = index - 1
while temp_index < 20:
temp_index += 1
op_msg[temp_index] = op_msg[temp_index + 1]
# Select new one
if op_index == 0 and op_msg[1] > 0:
op_index = op_msg[1]
elif action == 1: # Incoming alarm
for index in range(20):
if op_msg[index] == 0:
op_msg[index] = msg_nr
# Select new one
if op_index == 0:
op_index = op_msg[1]
else: # Loop in alarm
op_index = msg_nr
system.tag.writeBlocking([op_index_path, op_msg_path], [op_index, op_msg])
It still needs some work to make it... let's say sane.
But while I can see what's going on line by line, I still can't figure out the big picture (which is often a sign that it needs some rework).
I have the feeling there's a much simpler way, but without understanding the goal I'm left with just that, a feeling.
Though, now it's a bit simpler to read and reason about, so I'm a bit more comfortable to start simplifying things
Okay I will try to explane to you. It has to do with the thing we worked on yesterday.
The action and msg_nr are passed to this script when my alarm of the tag values prompt goes off (same prompt tags as yesterday so there are around 20 of these prompt tags).
All those action datatypes have this prompt tag.
if the one of the alarms of these prompt tags goes off (this happends when prompt tag value is > 0) then action = 1 so it will run this function and then action 1 of it.
so this part of your updated code.
if alarm goes away because it is being cleared. It will pass action = 2 and run:
msg_nr is the parameter that points to the right prompt tag that is >0. This parameter is passed when the alarm goes off just like action parameter.
L4_Active_Operator_Msg will be the array of msg_nr.
for example: if prompt tag of Action1 is >0 then msg_nr is 1 and the alarm goes off because this prompt is now >0 so it will pass msg_nr = 1 and action= 1
what must happen now is that the msg_nr is the first number in the L4_Active_Operator_Msg array.
if not one but 2 prompt tags are >0 then the second one that is >0 must be stored in the array after the first one. So after this there should be 2 msg_nr in the array.
as soon as one alarm is cleared the parameter action passes 2 so it wil run the action = 2 code. This code must delete the msg_nr of the alarm that is just been cleared and move the whole array so that the alarm that is still on is in the first place in the array
so Action1/prompt >0
array: [1]
now Action5/prompt also >0
array:[1,5]
alarm of Action1/prompt <=0
array: [5]
This is what must happen yes:
Is L4_Active_Operator_Msg supposed to be a queue then ?
Except you're not necessarily popping the first element ?
Are there always 20 elements in that array ?
I kind of feel like you're not using the right tools for this job.
I'm not sure because it code that rewrote into ignition of my company that I work for.
The values that will be in the array are the msg_nrs.
most of the time there will be 0,1 or 2 msg_nrs in the array because there are often 0,1,2 alarms on at the same time
def auto_select_operator_interaction(msg_nr, action):
tagPaths = []
arrayZero = []
if action == 2: # Outgoing alarm
# If action was selected, then unselect
if msg_nr == system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition"):
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", 0)
# Shift all active alarms from the selected one
for index in range(20):
if system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index)) == msg_nr:
temp_index = index - 1
while temp_index < 20:
temp_index += 1
index_van = temp_index + 1
system.tag.writeBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(temp_index), system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index_van)))
# Select new one
if system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition") == 0 and system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]") > 0:
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]"))
elif action == 1: # Incoming alarm
for index in range(20):
tagPaths.append("[Test SCADA Ignition]L4_Active_Operator_Msg[{}]".format(index))
tagValues = system.tag.readBlocking(tagPaths)
for index in range(20):
if tagValues[index] == 0:
tagValues[index] = msg_nr
# Select new one
if system.tag.readBlocking("[Test SCADA Ignition]OperatorIndexIgnition") == 0:
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", system.tag.readBlocking("[Test SCADA Ignition]L4_Active_Operator_Msg[1]"))
else: # Loop in alarm
system.tag.writeBlocking("[Test SCADA Ignition]OperatorIndexIgnition", msg_nr)
If you look in this code that I had earlier operatorIndex is being written by msg_nr or set back to 0.
I use this tag to point to prompt values again so they will display a text in my operator screen like I said yesterday
You guys are pretty quick with all the coding so I will try to see if the current solution you guys have given to me work and let you know if I managed. I'm not that quick with all this sorry for that. It's all very new for me
Not if elements from the middle of the list can be popped.
What I think he wants is just
del op_msg[index]
maybe ?
or
op_msg = [msg for msg in op_msg if msg != msg_nr]
But I still think the whole thing took a wrong turn at some point and there's a better way to do all this.
edit: side note
If you're in a situation where you want to be doing some_list[1:],
consider using a queue. I'm sure Java has some types that can be used for this, or there's collections.deque with .pop() and .popleft(). It even has a rotate() method !
It's not always worth it, but it's always nice to know it exists.