I’m working on numeric entry template that will automatically switch between metric and imperial, but only write imperial values to the PLC. Here are the template’s custom properties and parameters:
the key property here is the “value”. It is an indirect binding to the tag specified in the tagPath parameter. The processType parameter is an enumeration that gets passed into my conversion functions to determine the correct math to use. So for instance, we’ve standardized on using psi for pressure in imperial units and mbar in metric units. So when you pass “pressure” to my function, it multiplies or divides by 68.9476. If you pass “level” it does the math with the 0.3048 factor between feet and meters. Here are the functions for reference:
def convertToMetric(value, processType):
# Converts an input value to metric units according to the process type.
# Typically used for reading values FROM the PLC and converting for vizualization
# Acceptable process types: pressure, flow, level, temp
if processType == 'pressure':
newValue = value * 68.9476
elif processType == 'flow':
newValue = value * 0.227
elif processType == 'level':
newValue = value * 0.3048
elif processType == 'temp':
newValue = (value - 32) * 0.55556
else:
newValue = 'Invalid process type'
return newValue
def convertToImperial(value, processType):
# Converts an input value to imperial units according to the process type.
# Typically used for converting visualized values before writing TO the PLC.
# Acceptable process types: pressure, flow, level, temp
if processType == 'pressure':
newValue = value / 68.9476
elif processType == 'flow':
newValue = value / 0.227
elif processType == 'level':
newValue = value / 0.3048
elif processType == 'temp':
newValue = (value * 1.8 ) + 32
else:
newValue = 'Invalid process type'
return newValue
What I want is a numeric entry that, in metric mode, displays and accepts input in metric units, but converts those to imperial before writing to the PLC, while keeping the displayed value in metric. So it seems like a binding between my numeric entry’s value property and the custom property is out.
What I’ve done so far is first, create a script on the startup event for my numeric entry field that will read the value of the view.custom.value which is bound to the tag, and then, if necessary, do the conversion and write it to the object’s value.
That should get things initialized at least.
On my numeric entry’s value property, I have a change script attached:
It’s basically doing the other conversion script (to Imperial) if I have metric selected, and if not, just passing the raw value to it.
But, I have an issue.
If the value of the tag changes by any other means, the value in my input box will not change! I need to keep that synchronized, but without using a binding of some kind, the only other method I know is by using property change scripts. But if I put a property change script on view.custom.value as well as the value property on my object that writes to it with ITS property change script, what I’m worried about is the following sequence:
- Object’s property change script writes value to view.custom.value
- view.custom.value registers the write as a change
- view.custom.value executes its change script.
- Object’s value property is updated.
- Loop to step 1
Would having two property change scripts create a race condition where they are constantly executing because they are constantly recognizing their “writes” as a change even if the value doesn’t actually change? I’m only worried because I’m going to be dealing with floating point numbers and I’m afraid I’ll run into a situation where it detects a changed value because this time the floating point math had a result that was 0.00000000000000000000001 different than the last value.
Am I worried about nothing? Does simply writing to a property automatically trigger any property change scripts attached to it? If the value does actually have to be different to register as changed, does it handle floating point weirdness where you can’t get perfect precision with floating point numbers?






