I had a similar Blockly Script to this working yesterday (simplified to demonstrate the issue), but now cannot get the script to work as required. (I am getting NaN as result for any calculations). I have tried all the tricks I can see to try and work out what is wrong - any assistance would be greatly appreciated.
10:14:56.320 [ERROR] [.openhab.automation.script.ui.Test123] - Previous Y1 27.63 V
10:14:56.321 [ERROR] [.openhab.automation.script.ui.Test123] - Previous Y2 27.63 V
10:14:56.322 [ERROR] [.openhab.automation.script.ui.Test123] - M1 is NaN
10:14:56.322 [ERROR] [.openhab.automation.script.ui.Test123] - M1 is NaN
So the values are retrieved correctly from persistence, however any calculation with those Variables fail and produce NaN, even a simple multiply by 1.
10:25:12.511 [ERROR] [.internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Test123' failed: org.graalvm.polyglot.PolyglotException: SyntaxError: <eval>:13:6 Expected an operand but found .
m1 = (.add(1));
^
The only changes I can think I made was to remove RRD4j and MAPDB as persistence services. I am now using InfluxDB - but that has been my default for a few days now.
When though. If in OH 3.4, well Blockly now converts to a whole new version of JavaScript. If a snapshot of OH more than a week or so ago, the way that units are managed on Items was completely reworked and now perhaps Items that didnât have units now do.
That looks like a bug in the UoM block. All I can suggest there is to file an issue.
I had this working yesterday on the same 4.0.0 SNAPSHOT. All I have done in between is removed RRD4J and MAPDB. I have tried re-installing them but made no difference.
That is just a subset of what I am retrieving to demonstrate the issue. The actual rule is longer with more calculations in it. I need Now, 1 minute ago, 2 minutes ago, 3 Minutes ago.
If it worked before and doesnât now, something changed. If all you changed was uninstalling two persistence engines you have your culprit. Something about removing those two engines changed what historic state is returning.
16:53:37.092 [ERROR] [.openhab.automation.script.ui.Test123] - Previous Y1 27.6 V
16:53:37.093 [ERROR] [.openhab.automation.script.ui.Test123] - Previous Y2 27.63 V
16:53:37.116 [ERROR] [.openhab.automation.script.ui.Test123] - M1 is NaN
16:53:37.117 [ERROR] [.openhab.automation.script.ui.Test123] - M1 is NaN
No, you set m1 to 1*1 and then set m1 to (items.getItem('Shelly_UNI_Persist_1Min_Voltage_ADC')....before logging m1 for the first operation. You wipe out the 1 before you get a chance to log it.
Yes, thatâs why I said above it looks like a bug and an issue should be filed. The UoM blocks are not producing valid code. Hopefully your issue will be seen and fixed quickly.
So to try and get back up and running I have added inline scripts to perform the required functions.
I was expecting that once the Quantity is assigne dto a variable, that that Quantity would be carried through to the later calculations etc - But it appears that this is not the case - I end up with 0 as a result?
So I have added the following inline script to retrieve the persisted values:
I would however like to round the result to 1 decimal place, which also requires the Quantity again, so trying to use inline script with (and a few variants):
m1 = (Quantity(m1).toFixed(1));
But I always get an error:
09:11:44.186 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value)(...).toFixed is not a function
at <js>.:program(<eval>:17) ~[?:?]
at org.graalvm.polyglot.Context.eval(Context.java:399) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262) ~[java.scripting:?]
at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
I am sure my syntax is wrong - But I have no idea why.
I donât know if there is support for toFixed() on a QuantityType. Quantity is just a wrapper around the Java QuantityType. I donât see such a function anywhere.
Why do you need to round it in the rule? You shouldnât round numbers until the last moment (e.g. when you display it on a UI). This is particularly important if you are doing further calculations with that number because rounding errors can become huge in only a couple of operations.
If you must round/truncate here, youâre going to have to convert it to a number and then back to a Quantity. m1âs already a Quantity so it would be this convoluted path.
I think maybe part of my issue (besides the âbrokenâ blocks, is my understanding of String vs Quantity vs Number and where they need /have to be used.
An Item STATE is stored as a string, so before any âcalculationsâ can be performed it needs to be converted to a ânumericalâ format being either a Quantity or a Number?
A Quantity is a number with a UoM attached, such as 100kW, 100V, etc?
A Number is a plain number with no UoM attached, such as 100, 200, 159.764 etc?
What I donât seem to get is:
If a state of an item is retrieved from the item itself or from persistence and stored in a variable, it is still a string
Unless it is converted to a quantity? Is it then always a Quantity going forward in that variable? So in Blockly one would have to use the UoM blocks - which are currently broken (even in 4.0.0.M3)
The Plain Math Blocks are only used for numbers with no UoM?
So this extract:
Which produces (and works):
temp = (3.123).toFixed(1);
Resulting in:
3.1
Would not work for a Quantity type? It would only work for a Plain Number?
Maybe I need to back off a bit and wait for the UoM blocks to be fixed and then try again?
But you can only get state from the âget the historic state of the ItemâŠâ block. So if you want to do math with it, you need to convert it to a numericState or a quantityState.
No, itâs just the .state property of the Item is always a String. And by default Blockly uses .state unless told otherwise and it doesnât have the option to be told otherwise when getting the historic state.
Yes with the caveat that if you reassign the variable some other value, that new value might not be a Quantity.
Correct.
Correct. If you have a Quantity, you can only use the block from the Units of Measurement section to do comparisons and math.
The problem is that blockly cannot detect the type of the content of the variables which is a pity which is why I need to make assumptions, so I went for
Blockly cannot detect the type that is contained in a variable so it expects an item object.
This allows to iterate over a group of item members which returns a list of item objects