Math Functions

I have been using the ROUND function with no problem, but can’t seem to get CEIL to work. When I use ROUND, I can see the color of the instruction change as it should, but CEIL remains black.

For instance, this works:

tempBins = round(TotalProduct/ProductsPerBin)

but this does not:

tempBins = ceil(TotalProduct/ProductsPerBin)

What am I doing wrong?

You need to make a distinction between functions in the Expression Language and Jython/Python. The expression ceil() works fine without any extra work. Judging by your syntax, you’re referring to Jython.

For Jython, we have round() defined but not ceil() - I imagine this is a Python thing. To get ceil, do the following:

[code]import math

tempBins = math.ceil(TotalProduct/ProductsPerBin)[/code]

I will look for info on using Python libraries with FactoryPMI and a list of builtin (non-module) functions. We probably need to create it. There are a lot of powerful functions available.

Thanks Nathan, I’ll give that a try.

It would be helpful to add your tips into the FactoryPMI help (Contents>TechnicalReference>ExpressionLanguage>MathematicalFunctions). Is “round”’ the only function that works by itself?

The expression language should have all of its functions defined and documented. There is no notion of namespaces for expression functions, meaning that you type them and they work.

We’re referring to Jython (scripting) functions, which are very different from Expression Language functions. Most HMIs give you Microsoft VBA - you get whatever functions VBA supports. For FactoryPMI you get Jython, which includes Python functions. It’s like comparing the functions that you get in Microsoft Excel (expressions) to the functions in VBA that’s included with Excel (scripting functions).

A list of builtin, defined functions are available here. Here are a few example functions: abs(), len(), int(), round(), etc. ceil() is included in the math library.

Python also has many libraries (modules) that you can import for more functions. Examples include: math, cmath (complex), and random. For example:

import random message = 'Random number: ' + str(random.random()) fpmi.gui.warningBox(message)

Again, I’ll look into adding a reference for the modules and their functions that you can import in FactoryPMI. I would probably put it under: Contents>TechnicalReference>Jython>importable modules.

[quote=“Step7”]Thanks Nathan, I’ll give that a try.

It would be helpful to add your tips into the FactoryPMI help (Contents>TechnicalReference>ExpressionLanguage>MathematicalFunctions). Is “round”’ the only function that works by itself?[/quote]

Hello,

For the sake of completeness, here are the Python modules that you can use in FactoryPMI:
[ul]
[li]base64[/li]
[li]bdb[/li]
[li]bisect[/li]
[li]calendar[/li]
[li]cmd[/li]
[li]colorsys[/li]
[li]commands[/li]
[li]ConfigParser[/li]
[li]copy[/li]
[li]copy_reg[/li]
[li]difflib[/li]
[li]dircache[/li]
[li]dospath[/li]
[li]fileinput[/li]
[li]fnmatch[/li]
[li]formatter[/li]
[li]fpformat[/li]
[li]gzip[/li]
[li]htmlentitydefs[/li]
[li]htmllib[/li]
[li]httplib[/li]
[li]javaos[/li]
[li]javapath[/li]
[li]linecache[/li]
[li]marshal[/li]
[li]mimetypes[/li]
[li]ntpath[/li]
[li]nturl2path[/li]
[li]pdb[/li]
[li]pickle[/li]
[li]posixpath[/li]
[li]pprint[/li]
[li]Queue[/li]
[li]random[/li]
[li]re[/li]
[li]repr[/li]
[li]shutil[/li]
[li]site[/li]
[li]socket[/li]
[li]sre[/li]
[li]sre_compile[/li]
[li]sre_constants[/li]
[li]sre_parse[/li]
[li]stat[/li]
[li]string[/li]
[li]StringIO[/li]
[li]tempfile[/li]
[li]urllib[/li]
[li]urlparse[/li]
[li]UserDict[/li]
[li]UserList[/li]
[li]UserString[/li]
[li]xmllib[/li]
[li]zipfile[/li]
[li]zlib[/li]
[li]future[/li][/ul]

Also, I just want to re-iterate that the expression language and the scripting language are completely and utterly separate. Don’t look at functions under the expression language docs and think that they will translate over to action scripts.

Here is a reference of Python modules. The list doesn’t exactly match up with the FactoryPMI Jython modules. The functions will be the same for the common modules.

Ok, this is probably a dumb question, but that never stopped me before. Is there a way to get python modules to work in FPMI if they are not in the list above? I’ve found some nice modules that I have been playing around with, but can’t seem to import them.

Yes and No.

You’d have to copy-and-paste them as app.* modules. Its tricky, though, because the scoping rules are a bit different, so you may have to mess with imports. Also, you’ll have to resolve any dependencies that that module uses. It can be done, but its a pain. Are there standard libraries that are missing that you’d like to see?

No standard libraries, but I’ve been experimenting with http://www.vpython.org/, and found a few things that I could use. I’m trying to add graphical features that go a little beyond what I can do with images. Being able to programatically create graphics is more to my liking.

Ah, that might be a bit tricky to integrate. I know this is a bit of a tease, but you’re going to like our native 2D drawing feature, which should lend itself to programatically-created graphics very well. Its still a ways off, though, sorry.

Ok, what if I came up with a .py script that does what I need- can I call it with the fpmi.system functions? I tried various flavors of fpmi.system.execute([“python”, “test.py”]), but didn’t get anything to work.

What I’m trying to do is dynamically draw what the machine just produced. I have the exact data points, it it should be pretty easy to display the exact dimensions and out-of-tolerance points. I could do it with a graph, but a drawing would be awesome.

No, you wouldn’t execute it like that, that would have the python on the client machine run that script (actually, maybe that is what you want? I’m not sure…)

I think you want to import it into your project’s global script modules, but I don’t see where it is going to draw this thing…

Now, I might be opening a can of worms with this, but take a look at this window (You’ll need to be running the 3.2.0 beta. And, you’d probably want to put the button code in a timer to continually draw, as normal repaints will clobber your drawing…)

This example uses Java2D. See the Java API for a reference, or Google for tutorials.
drawcanvas.fwin (14 KB)

Now that I think about it, we should totally have a “PaintableComponent” component, where you provide its painting code in Jython using Java2D. All you’d need is a hook into the repaint event.

I think we might just have to sneak this into the 3.2.0 release…

Thanks for the idea!

Bring it on. I've slogged through Siemens stuff for 20 years, and if I can handle German software, I can handle anything.

I actually gave that some thought. I realize that some features might just be too intense for a low end client PC, so I would have no problem popping up a message telling the tech to go to a different PC to get to the advanced graphics if the python libraries weren't installed on the local PC. That's definitely an option I could live with.

[quote="Carl.Gould"]I think you want to import it into your project's global script modules, but I don't see where it is going to draw this thing...
[/quote]
That's why I was wondering if I should just launch a stand-alone Python script from fpmi. I could pass in the data points as parameters or keep them in a file or something. I'm just brainstorming for now, but don't mind putting in the effort if it has a prayer of working.

Yeah, if you wanted to launch the python script externally on the client machine, you could do that just fine. You could even write the script or an input file for the script dynamically through FPMI with the fpmi.file module.

The tricky part is making sure Python is installed on your client machines.

I just installed the beta version, and now I get a message when I launch a project. Any ideas?

java.lang.NoClassDefFoundError: com/calmetrics/factoryhmi/application/gateway/DataSet
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at com.inductiveautomation.factorypmi.plugins.reporting.ReportingDesignerHook.(ReportingDesignerHook.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.inductiveautomation.factorypmi.designer.model.DesignerPluginManager.loadPlugins(DesignerPluginManager.java:62)
at com.inductiveautomation.factorypmi.designer.FPMIDesigner$2.run(FPMIDesigner.java:434)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.calmetrics.factoryhmi.application.gateway.DataSet
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
… 29 more

You didn’t upgrade the reporting plugin at the same time. Make sure when you run the beta installer to choose custom, and check the reporting plugin.

Got it, thanks.

I just took a look at the window: Awesome! I’ve got an immediate application where I am using a lot of lines on my GUI to indicate product paths, and until now I have been using a painful method of creating images of lines. Each time I needed a different color, thickness, or type of line I had to start over. But this gives me the possibility of generating any kind of line type, from a simple line to complex line types (such as railroad tracks) dynamically. I’ll get this working, and then it’s on to 3d…

Ok, I’ve been experimenting with this stuff with pretty good results. But I am having a problem understanding when windows refresh/update on their own.

For instance, I took your sample code and changed it so that I draw only lines on the screen (no polygon or fills), so it has a transparent effect. Basically, I’m just drawing lines on top of my existing screens. For my testing, I stuck the code on a button, and on the click event I read the coordinates from the label and create the lines. I erase the previous line with “canvas.update(g)” just before drawing the line. This works fine.

But, what I want to do is execute the same code when the screen opens or when someone returns to this screen after tabbing to another screen (my line disappears when the screen refreshes for any reason, which I would expect). But when I add the code to the window getfocus or internalframeopened/activated events, at the most I see the line flicker for a moment. So, it looks like the screen refreshes on its own after it opens or gets focus. Do I have access to this event/action somehow?