Iām torn. Maybe thatās a good idea, but maybe not.
We will see how this evolves.
ā Christoph
Iām torn. Maybe thatās a good idea, but maybe not.
We will see how this evolves.
ā Christoph
Iām having troubles with implementing UoM as well. Quick question: Is this supposed to work or am I doing something wrong? I am trying to do calculations with gas consumption, which is in cubic metres.
rule "Test"
when
System started
then
val n = 5|m3
end
The expected warning about the unused value aside: Iām getting a:
[ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'Test': unexpected token 8
Putting the cubic metres in quotes doesnāt help. Other units like āWā or āweekā work just fine.
Iām on 2.5.0.M1 but 2.4.0 produces the same result.
Thanks a lot in advance for any input!
Can you try instead:
val n = 5|mĀ³
It doesnāt show the error for me when I use it this way in a rule.
If that also works for you the documentation needs to be updated.
Oh no! Yes that works. I feel a bit stupid now. Although in my defense the āpower of threeā isnāt even on the Mac keyboard and I hadnāt considered such a rare character to be working.
Thanks a million for the quick response!
Excellent news that it now works!
The documentation also contains several wrong unit symbols, so Iāve created a PR to update it:
Thanks
Hi, itās me again. I am using lots of Functions and Procedures and found that any UoM argument needs to be of QuantityType<
Number>
or the rule wouldnāt execute. E.g. QuantityType<
Angle>
wouldnāt work. Is there anything I can do about that or is that normal / āstandard procedureā?
Having said this, I found that a Procedure or Function doesnāt accept a negative angle as an argument. One use case is handing over a negative elevation (sun below horizon). In case anyone is wondering.
test.rules:
rule "Test"
when
System started
then
val Procedures$Procedure1<QuantityType<Number>> elevation = [ angle |
logError("Test", "Elevation is: " + angle)
]
// VSCode: Type mismatch: cannot convert from QuantityType<?> to QuantityType<Number>
// Log: Configuration model 'test.rules' has errors, therefore ignoring it: [xx,xx]: no viable alternative at input '|'
// elevation.apply(-5|Ā°)
// elevation.apply((-5)|Ā°)
// VSCode: Type mismatch: cannot convert from QuantityType<?> to QuantityType<Number>
// Log: Nothing logged (rule works)
elevation.apply(5|Ā° * -1) // Elevation is: -5 Ā°
elevation.apply(-5|"Ā°") // Elevation is: -5.0 Ā°
// No errors
elevation.apply(5|Ā°) // Elevation is: 5 Ā°
elevation.apply(5|"Ā°") // Elevation is: 5 Ā°
end
Iām also curious about the sudden conversion to floating point in case of (-5|āĀ°ā).
It would be great if someone could shed light on this.
Thanks,
Jens
Take anything VScode says about this with a pinch of salt. These are new features and may not be fully recognized by the extension yet, so worth seeing what happens when you actually execute them.
Please keep experimenting and let us know!
I think thatās just an oddity about rules use of Number and parsing - hyphen, it crops up all over the place unconnected with UoM.
Thanks for the feedback! I did some further experiments and here is an updated version of the rule that does run successfully with a negative angle.
// VSCode goes up in flames, but Rules DSL is fine with the import
import org.eclipse.smarthome.core.library.dimension
rule "Test"
when
System started
then
// Strongly typing with Angle instead of Number makes the procedure
// accept negative angles. VSCode and Angle are not friends, though.
val Procedures$Procedure1<QuantityType<Angle>> elevation = [ angle |
logError("Test", "Elevation is: " + angle)
]
elevation.apply(-5|Ā°)
end
This is what happened: I once got an error by the Rules DSL which I thought was from the import and didnāt try that ever again because I thought the import wouldnāt work. So I stuck with Number. Turns out the import works fine. And with it,
QuantityType<Angle>
(etc.) can be used. The procedure in my example then accepts negative angles. I still think Number not accepting a negative angle is a bug. But it works now! And everythingās strongly typed. Yay!
Iāve not seen it do this. My example does not work.
Number:ElectricCurrent ffjj " Value [%.1f mA]"
Am I missing something? I cannot see it change when I give it a value of 100 or 0.1. Result printed is always mA
Apologies for hijack
I think you need to more specific, like 100 A
EDIT - oh wait, did you mean automatically scaling a display, like Item vale 23005 A getting displayed as 23.005 kA? In theory [%f.3 %unit%] could do that, but I donāt think itās implemented?
Hereās another thing Iāve learned. Persistence doesnāt return QuantityTypes so we sometimes need to convert a Number or primitive numerical value to QuantityType. This is how itās done.
import org.eclipse.smarthome.core.library.unit.SIUnits
rule "Test"
when
// Also triggered upon saving of file
System started
then
// This can be any item of type Number:Power (W)
val item = WashingMachinePower
// Its state is a QuantityType<Power> (W)
val state = item.state
logError("Test", "State: " + state)
// Persistence produces a value of type DecimalType
val average = item.averageSince(now.minusMinutes(5), "rrd4j")
logError("Test", "Average: " + average)
// Convert to QuanttyType using the constructor
// QuantityType(Number, javax.measure.Unit)
val averageTyped = new QuantityType(average, SIUnits.WATT)
logError("Test", "Average (typed): " + averageTyped)
// A way to convert to QuantityType from double using static
// factory method
val typed = QuantityType::valueOf(42, SIUnits.WATT)
logError("Test", "Value 42 (typed): " + typed)
end
See also:
Now what we need is a bit of nifty code to interrogate the āliveā Item to establish UoM, and automatically choose the ārecreatedā value UoM.
I can see that causing odd issues when the unit of the live Item gets changed after some data already recorded.
Haha! Now that you mentioned it I got worried and checked my persisted values. Letās say I have the following item. As the group name indicates is is persisted to DB every minute (for debugging).
Number:Power TestPower "Test [%d W]" (PersistDBEveryMinute)
When I do the following:
PowerItem.postUpdate(2000|W)
The number 2000 is written to DB. If I do the following:
PowerItem.postUpdate(2|kW)
You guessed it: The number 2 is written to DB. Shouldnāt the unit as defined in the item definition (in this case: W) be used? In my opinion this is really, really bad. It means that there either needs to be a proxy item for persistence or the postUpdate must never receive a different unit.
I would suggest to have persistence store values in their canonical representation (SI units for most, imperial units for some). To avoid unit conversion errors, I would even adhere to persisting in SI, according to a defined convention (e.g. metre as canonical length unit).
Whenever UoM would be invoked, it would always know the starting unit. Any unit conversion requested would then use the proper factor.
Oh. Um. That is ā¦ undesirable. I mean, I understand the limitations of the persistence services not (yet) dealing with UoM properly, but thatās a nasty consequence.
This is indeed really, really bad. I would file this as a critical bug. The UoM seems to be causing more problems than it solves.
I totally understand your pain. Been there. Especially since there is no reason why rules have to fail.
IMHO that is something that should be fixed.
Some automatic type conversion would help.
I myself would not try the uom again until thats fixed.
Well, nothing is going to change for OH2.3 at this stage (the thread is from nearly four years ago).
Let us know if you want help with something specific.