SQL tags in a loop

I was wondering what would be the best approach to do the following.

  1. When I click on a button I want a certain page to load. On this page will be shown 99 checkmark boxes along with a numeric label and a button at the bottom called Finish. The numberic label will be the actual machine number. I also have 99 SQL tags defined with the following format logout1 - logout99. Here is what I would like to do, On this screen I would like to use the checkboxes and say I check boxes 1, 2, 6, 10, 50, and 99. Then I click the button that says finish. Once I do that the SQL tags which are associated with 1, 2, 6, 10, 50 and 99 will toggle on then off, all other SQL logoff tags remain unchanged. Any suggestions?

Here is a sample of a loop, but this is used with SQL tables. I was wondering if I changed some of it to be fpmi.db.getTag(“logout”+k) or something similar, or is there a better way?

def shift_id(shift_id):
import fpmi

num_mach=99

fpmi.db.runUpdateQuery("UPDATE crossover SET mach_num=0 WHERE field>=1 and field<=%s" % (num_mach),"mocrosoft")

k=1
table = fpmi.db.runQuery("SELECT mach_num FROM interim WHERE shift=%s and mach_sel=1" % (shift_id),"mocrosoft")
for row in table:
	fpmi.db.runUpdateQuery("UPDATE crossover SET mach_num=%s WHERE field=%s" % (row[0], k),"mocrosoft")
	k=k+1

Ok, this might get you started…

You can loop through components fairly easily, with the code below. To make things as simple as possible, this is what I would do:

  1. Create a custom component for your check box. That is, create a check box, add a dynamic property for the ID (integer), bind the text of the check box to something like "Machine "+{id…}. Then create a custom palette, and add the check box to it. Now you can just copy/paste, or add new copies of it, all over and all you need to change is the id value.

  2. Put all of the check boxes into a panel, with nothing else. That way you only have 1 type of component in the container. Then you can do something like…

  3. On the button’s action performed, loop through the check boxes and use their ID properties to update the tag you need:

for comp in event.source.parent.getComponent("panel").components:
	fpmi.tag.writeToTag("Tag%d" % comp.getPropertyValue("id"), comp.selected)

So, the main trick here is that you can loop through the components of any container. Since we know they are all check boxes, we don’t have to do any other checking, we can just reference the “selected” property, and call getPropertyValue for the id property (NOTE: usually in script you can just refer directly to the property, like comp.id, even if it’s dynamic… it wasn’t working for me through this method, but using the function did work).

Anyhow, this might not be the total solution for you, but hopefully it’ll give you some ideas and room to run.

Regards,

This may sound like a dumb question but is a panel and a container the same thing? I have looked thru the user manual for the differences between containers and panels and it almost appears that the two names are interchangable but I want to know for sure. Thanks for the info it gives me a good starting point.

I also have the question the link that is on here somewhere for Jython, will that lead me to details about these unique commands such as the FOR COMP? Just curious because it would be interesting to know how these commands are structured and work.

[quote=“Colby.Clegg”]Ok, this might get you started…

You can loop through components fairly easily, with the code below. To make things as simple as possible, this is what I would do:

  1. Create a custom component for your check box. That is, create a check box, add a dynamic property for the ID (integer), bind the text of the check box to something like "Machine "+{id…}. Then create a custom palette, and add the check box to it. Now you can just copy/paste, or add new copies of it, all over and all you need to change is the id value.

  2. Put all of the check boxes into a panel, with nothing else. That way you only have 1 type of component in the container. Then you can do something like…

  3. On the button’s action performed, loop through the check boxes and use their ID properties to update the tag you need:

for comp in event.source.parent.getComponent("panel").components:
	fpmi.tag.writeToTag("Tag%d" % comp.getPropertyValue("id"), comp.selected)

So, the main trick here is that you can loop through the components of any container. Since we know they are all check boxes, we don’t have to do any other checking, we can just reference the “selected” property, and call getPropertyValue for the id property (NOTE: usually in script you can just refer directly to the property, like comp.id, even if it’s dynamic… it wasn’t working for me through this method, but using the function did work).

Anyhow, this might not be the total solution for you, but hopefully it’ll give you some ideas and room to run.

Regards,[/quote]

I don’t have any jython links off hand, but I’ll try to clarify a few things:

  1. Panels & Containers - yes, their essentially interchangeable. They mainly just hold other components.

  2. That jython command is simply a type of FOR loop. ‘comp’ is my own variable name. One thing about python/jython that makes it unique is the very robust way it can handle lists & collections of items. In this case, we’re getting a list of all the components hosted inside the panel with event.source.parent.getComponent(“panel”).components, and we can loop through them by saying for [variable_name] in [list]: It’s just going to go through each item, temporarily putting it in our variable that we just implicitly declared.

I did a very quick search and found a page with more information about lists in python. In general it’s a wide topic - like I said, lists are one of the strengths of python- but you’ll see what’s called the “For-In” construction described part way down the page:
http://effbot.org/zone/python-list.htm

Regards,

Thanks for all the help. I had figured out that panels and containers are similar in I used a simple program in which I used your script and only had one component inside the container then instead of doing the FPMI tag update I did a GUI message display then changed the name of the window a couple of times to verify what it was picking up. So I finally got that working. Then I ran into another problem.

Some of our machines are not online yet. What was happening when I ran the script and had all 99 configured is I would get a write timeout fault. Now here is a question about this fault, why would it not write any of the tags when this fault occurs? Is this normal?

What I ended up doing is, I have the _Error flag from KepServer comming back so I added another property binding to this SQL tag. Then i added the following commands to yours to accomodate the fault;

value=comp.getComponentValue(“fault”)
If value == 0:
fpmi.tag.update (command)
else:
k=k+1

This corrected the problem that if a machine was not online it would not try to send any commands and it would not get a timeout issue. I was not sure if I needed anything after the else command so I just thru something in there that means nothing.

As it stands I tested it today at work and it now seems to work fine. Thanks again to all at IA and their great work.

[quote=“Colby.Clegg”]I don’t have any jython links off hand, but I’ll try to clarify a few things:

  1. Panels & Containers - yes, their essentially interchangeable. They mainly just hold other components.

  2. That jython command is simply a type of FOR loop. ‘comp’ is my own variable name. One thing about python/jython that makes it unique is the very robust way it can handle lists & collections of items. In this case, we’re getting a list of all the components hosted inside the panel with event.source.parent.getComponent(“panel”).components, and we can loop through them by saying for [variable_name] in [list]: It’s just going to go through each item, temporarily putting it in our variable that we just implicitly declared.

I did a very quick search and found a page with more information about lists in python. In general it’s a wide topic - like I said, lists are one of the strengths of python- but you’ll see what’s called the “For-In” construction described part way down the page:
http://effbot.org/zone/python-list.htm

Regards,[/quote]

Your fault check is fine. I wouldn’t be too concerned about the write errors, it’s true that you might expect a different error (probably a simple E_FAIL), but there’s a variety of situations that could affect this. At any rate, since you have a way to check if their up or down, it’s always correct to do so.

In terms of what to do with the ELSE: first off, if there isn’t an else case, you can just leave it out. It’s ok to just have the IF and what to do after it.

If you find yourself in a situation where you just need to “do nothing”, python has a convenient “pass” keyword. That is, the word pass by itself make a valid line of code that doesn’t do anything.

Hope this helps,

Colby, it was not so much the fact that I had write errors, what was really concerning me was the fact that if write errors occured, none of the data, even the units that were online were getting changed.

Example: Machine 1,2,3,52,53,54 and 55 were online. All 99 are configured. When the code ran it would come up with 99 write errors. And if I looked at the data it did not change any of the values from the active machines. That is why I added in the fault check routine.

What I was curious about is if this is suppose to be normal. I mean I can see it not wanted to write to one that is not online. But why would it not write to any of them?

[quote=“Colby.Clegg”]Your fault check is fine. I wouldn’t be too concerned about the write errors, it’s true that you might expect a different error (probably a simple E_FAIL), but there’s a variety of situations that could affect this. At any rate, since you have a way to check if their up or down, it’s always correct to do so.

In terms of what to do with the ELSE: first off, if there isn’t an else case, you can just leave it out. It’s ok to just have the IF and what to do after it.

If you find yourself in a situation where you just need to “do nothing”, python has a convenient “pass” keyword. That is, the word pass by itself make a valid line of code that doesn’t do anything.

Hope this helps,[/quote]

Ah, I see. I agree that that is strange… I’ll have to look into it a bit more and get back to you.

What was the error?

The error message that was showing on the screen was WRITE TIMEOUT. It was it said, even if I clicked on the arrows it did not show any more data than WRITE TIMEOUT. I am not sure why if one channel does a WRITE TIMESOUT why it would not write any channels. In this case each channel is referenced as a device.

What was the error?[/quote]

Hi-

Just wanted to follow up with the progress so far: just using the simulator I haven’t been able to replicate the problem, the items that are disable return the correct E_FAIL message. Obviously looks like one of those “real world” problems that can’t be replicated with a simulator, so I’ll look into that next.

Also wanted to comment on something we discussed on the phone, which is the fact that the disabled tags are reporting a “not connected” status. Turn out that this is the status they have when they are initialized, and so they stay like that because they never receive an update from the OPC server. If they do get an update, you see them change to E_FAIL, because that’s what the server gives FSQL. All said and done it’s not a problem, and they ARE connected, as soon as the points come online in the server the values will pop in.

Regards,