Generating random values in rules DSL in OH3

Right now the Getting Started tutorial mostly presents JavaScript (I’m considering adding a Blockly page but time is running out). I’ll see how I can work it in there or in the Rules DSL docs. As I mentioned on the tracking issue, I think the whole Rules docs need a complete overhaul now that building rules in the UI is working.

2 Likes

Ok, another thing I really can’t seem to succeed with in the GUI, might as well continue in the same thread…

In a rule in a .rules file I use the following

(Utetemperatur.state as QuantityType<Temperature>).doubleValue

to get the value of a Number:Temperature Item into decimal form. When I do this in a rule in the GUI it simply says

Temperature cannot be resolved to a type.

What am I doing wrong now?

If I recall correctly, you needed an import for Temperature already in the .rules file. So look at your import and put the package path before Temperature. I think it’ll look something like javax.measure.quantity.Temperature.

No, I have nothing like that in the file. And javax.measure.quantity.Temperature isn’t recognized either (altough there seems to be something named like that when I Google it).

Then I’m not sure. But a different question is do you really need that? What’s the full line and why do you need the doubleValue?

That’s actually a legitimate question :stuck_out_tongue: It’s the same rule as the random stuff discussed earlier in this thread. I’m sending temperature readings to a stupid API which thinks my sensor is broken if I don’t periodically send values, and they have to be different than the value I sent before. Since my sensor only reports values with one decimal it sometimes happens that it’s stable for too long. So I add a random second decimal before sending the value to eliminate the risk of it being tha same as the last. I hope you’re following :sunglasses:

The entire relevant code looks like this:

rule "Utetemperatur changed"
when
        Item Utetemperatur changed or
    Time cron "0 5/20 * * * ? *"
then
        var float slumptemp = (Utetemperatur.state as QuantityType<Temperature>).doubleValue + rand.nextFloat()*0.04
        sendHttpGetRequest("http://<removed_url>&t=" + slumptemp)
end

OK, I think you don’t need to use “Temperature” here. I think you can use “Number” instead and achieve the same result. You are stripping the units off of the value anyway so it really doesn’t matter what type it is beyond just Number.

This leaves the original question unanswered I know, but it should get you to the next step at least.

However, I see a few other Rules DSL problems with the rule which might be done better.

For one you are forcing the variable to be a float but pulling a double from the Item’s state. And then adding a float to that. You should stick to floats for all of these for one. For a second, get rid of the type for the the variable. It’s not needed and there will be a whole bunch of conversions taking place in that one line to get to it. This is known to drastically slow down the loading and parsing of rules.

var slumptemp = (Utetemperatur.state as QuantityType<Number>).floatValue + rand.nextFloat()*0.04

In fact it might even work without the .floatValue.

In general Rules DSL is going to try really hard to convert all the numbers and results of calculations to BigDecimal. Don’t fight it. Only force it to a primitive when you absolutely have to.

Hmmm… I’ve been a PHP developer for many years, and all the strange types in these rules really gets me confused every time. And also the lack of a good reference guide…

Anyway, changing Temperature to Number seems to get me closer to a solution. Not all the way though. Neither floatValue, doubleValue or leaving it out completely work, they all tell me it “cannot convert from double to float” or “cannot convert from BigDecimal to float”. I’m too tired now, guess I’ll fix this tomorrow instead…

Maybe the doubleValue is there for a reason. My rules DSL is quite rusty at this point and I never did have a whole lot of experience with QuantityTypes in Rules DSL anyway.

Ok, this made me think it actually might be a good idea looking at some of the new stuff, so I started playing with Blockly here. It’s actually really fun :stuck_out_tongue:

This is my first Blockly script ever:

(The variable Utetemp really seems superfluous, but for some reason I couldn’t put the item state directly in the addition box)

Is there any way to do more fancy thing, like in my example a sendHttpGetRequest() using Blockly? Or is it limited to the stuff found in the tool box?

(I know, this thread is really floating away from the topic. Sorry for that :sunglasses:)

1 Like

It’s hard to tell but indeed it looks like “get item state” has a different plug shape from variable. Kind of odd. I’ve not explored much with Blockly yet (beyond helping my seven-year-old make wonderful music in Scratch) but I need to. A page needs to be written about it in the Getting Started Tutorial.

Unfortunately, most of the OH Actions are not (yet?) supported. So those will have to be done in code. I do expect the capabilities of Blockly to grow over time. I also hope that blockly will be a bridge for users to eventually transition to JavaScript rules since when you click on the Code tab with Blockly you should see the JavaScript underlying the blocks. It can be quite a good way to learn.

It’s your thread. I read so many and respond to so many that I usually lose track of what a given thread was originally about anyway. I’m sure that causes much frustration to the other moderators.

But that can’t be done once I’ve started with Blockly, can it? The code seems to be read-only. Guess I could simply copy the generated code to a new script, but it feels like it’ll destroy the fun of Blockly :smiley:

Unfortunately not I think. You can’t switch between the two, at least at this time. But if it were possible, once you manually edit the code you wouldn’t be able to go back to Blockly.

So now I just have to find out how to do a http get from a js script…

Or just use Rules DSL. Nothing says you have to use JavaScript.

It’s easier with the helper libraries. But I’ve also some examples at Experimental Next-Gen Rules Engine Documentation 5 of : Actions which should be mostly correct. I don’t know if the sendHttp Actions have changed in OH 3.

I try to stick with simple DSL.rules. I’ve rewritten a lot of my rules for oh3. I’ve moved logic to bindings and external scripts. I’m working on a new binding to handle rules in java. I’ve never liked scripts for writing logic (jython/javascripts/dsl)

Well, that’s what I tried earlier in this thread. The reason for trying JS instead was that I didn’t seem to reach the goal line using DSL :stuck_out_tongue:

It’s good to follow a general direction. Currently I’m trying around with all possible ways to do stuff, trying to decide what path to follow. The first thing I’m trying to achieve though is getting rid of all .rules files, after having moved in all items and things into the GUI :slight_smile:

Sounds like a good strategy. In general I find it much harder to debug scripts, that’s why I try to keep as much logic as possible in java where I have good debug alternatives and testingframeworks.

Will be interesting to see if this graphical rules stuff (blockly) works. I have bad experiences doing programming in graphical tools, but I guess it’s a lot better now looking at for instance node red.

Just for anyone interested, I finally solved this rule. The key was to skip any floats and use only double instead. ie:

var double slumptemp = (Utetemperatur.state as QuantityType<Number>).doubleValue + rand.nextDouble()*0.04

Seems like I’ll stick to rules DSL for the time being. At least for this rule :sunglasses:

1 Like