Simple rule to generate value (state) of item from other item states

A couple of days in to trying to climb the curve of openHAB, and I’ve reached the heady heights of trying my first rule … and failing miserably. I’ve abandoned PaperUI other than as a guide to structure/content of configuration files.

So, as a very simple scenario, I’m looking at the OID codes from my printer via the ‘snmp’ addon, and I want to determine the amount of black toner remaining. That works fine up to a point; I can get the maximum and current toner amounts (so essentially job done), but I wanted to generate a % remaining item, and thought to do so with my simple rule.

Printer.things

Thing snmp:target:Printer "Printer" @ "Study" [ hostname="192.168.2.200", protocol="v2c" ] {
    Channels:
        Type number : Max_Black "Max. Black:" [ oid=".1.3.6.1.2.1.43.11.1.1.8.1.4", mode="READ",datatype="UINT32" ]
        Type number : Cur_Black "Cur. Black" [ oid=".1.3.6.1.2.1.43.11.1.1.9.1.4", mode="READ",datatype="UINT32" ]
}

Printer.items

Number Max_Black "Maximum black:" { channel="snmp:target:Printer:Max_Black" }
Number Cur_Black "Current black:" { channel="snmp:target:Printer:Cur_Black" }
Number Lvl_Black "Black:"

Printer.rules

rule "Printer_test"
when
  Item Max_Black received update
then
  var Number num1 = Max_Black.state as Number
  var Number num2 = Cur_Black.state as Number
  var Number num3  = num2 * 100 / num1
  Lvl_Black.postUpdate(num3)
end

TheSutherlands.sitemap

sitemap TheSutherlands label="Main Menu"
{
    Frame {
        Text item=Max_Black
        Text item=Cur_Black
        Text  item=Lvl_Black
        }
}

So, trying this in the Simple or ClassicUI, I get the two channel readings ok (Max & current black), but I get an ‘ERR’ or nothing for the calculated black%. I also see from logging within the rule that num3 has a value of the form 40.00000000, which is also throwing me.

My immediate thoughts were type mismatches, but it is difficult to see item/value type in openHAB compared with doing so in python or javascript. I can see that this must be a basic misunderstanding on my part, but I’m getting to the point where I am feeling frustrated. There is plenty of documentation around (and I’ve certainly gone through a lot of it), but it appears to be written almost as a reference guide for people who are already familiar with openHAB.

Any help would be much appreciated :wink:

As a first step I would use some logInfo lines in order to show the current value of the variables.
Like:
logInfo("Printer_Test","num1: {}", num1)
which would print a logline showing the content of num1.

Why, what would you expect?

Rules DSL is at once sloppy about typing in general and picky in some specifics.

Despite num3 being declared a Number type, I think I’d try posting it as the always-works string version.

Lvl_Black.postUpdate(num3.toString)

Yep, tried and I get the correct results for all three variables, but wondered why I get 40.00000000 for 1000*100/2500.

Yep, tried casting numbers in variable ways including “num3.toString.”

Does the logic behind the files and the rules file look ok? As a beginner, I don’t even know this fact ;(

It all looks reasonable.

Log out all the values, and let us see results.

Make sure you only have one rule with that name.

I’d add some formatting to your Item for display.
Number Lvl_Black "Black: [%d]"

It is possible to enter the rule with only one number defined, but tidying that up is just a finesse to do after the basic function is working.

Firstly:

logInfo("Printer_Test","num1: {}", num1)
logInfo("Printer_Test","num2: {}", num2)
logInfo("Printer_Test","num3: {}", num1)

results in:

2020-05-18 09:35:16.391 [INFO ] [.smarthome.model.script.Printer_Test] - num1: 2500
2020-05-18 09:35:16.392 [INFO ] [.smarthome.model.script.Printer_Test] - num2: 1000
2020-05-18 09:35:16.394 [INFO ] [.smarthome.model.script.Printer_Test] - num3: 2500

Secondly:

logInfo("Printer_Test","num1: "+ num1)  
logInfo("Printer_Test","num2: "+ num2)
logInfo("Printer_Test","num3: "+ num3)

results in

2020-05-18 09:43:16.397 [INFO ] [.smarthome.model.script.Printer_Test] - num1: 2500
2020-05-18 09:43:16.399 [INFO ] [.smarthome.model.script.Printer_Test] - num2: 1000
2020-05-18 09:43:16.400 [INFO ] [.smarthome.model.script.Printer_Test] - num3: 40.00000000

Obviously, num3 should be 40.

If you don’t want to see the unnecessary decimal places use number formatting on the displayed value.

Why should it? You didn’t tell the dumb machine you wanted an integer.

Why would you care, though? You can easily control format at point of display. Who cares what internal storage format.

var Number num3 = (num2 * 100 / num1).intValue

(My apologies, there was a typo in the first logging block (as I have just seen now looking at the forum post). I thought the two slightly different log statements were giving a different value for num3. Totally incorrect.)

I am not at all bothered about the format of num3 (other than curiousity). I still have the original problem that when num3 is assigned to the item Lvl_Black item it is either not shown in the sitemap or it is given an ‘Err’ value. The rule appears to work, but the item doesn’t pick up the calculated value.

There’s only three things that can happen when this is executed;
It blows up, with a report in your openhab.log
It works, and a change is logged in your events.log
It works, but causes no change in target Item state, and so no log.

You can add logging if in doubt

logInfo("test", "before " + Lvl_Black.state.toString)
Lvl_Black.postUpdate(num3.toString)
Thread::sleep(1000) // delay for effect, diagnostic only
logInfo("test", "after " + Lvl_Black.state.toString)

Thank you, that’s a very useful statement for future debugging.

So, in this case, it appears to succeed in that Lvl_Black.state.toString appears to hold “40.00000000” as demonstrated by your before and after logInfo around the postUpdate, but there is nothing logged in events.log

I have just noticed a log generated when I run the BasicUI (the UI which indicates an ‘Err’ for Lvl_Black):

2020-05-18 14:45:24.666 [WARN ] [ui.internal.items.ItemUIRegistryImpl] - Exception while formatting value '40.00000000' of item Lvl_Black with format '%1.f': Conversion = '1'

Nothing is shown in the log (nor on screen for Lvl_Black) when I use ClassicUI.

Now you must look at your Item definition and your sitemap entry (or entries, it is allowed to have more than one for any given Item)
40 will not fit into format [ %1.f ], perhaps you meant [ %.1f ]

There is no formatting in my files (as can be seen at the top of the post) …, and I’ve just double-checked my actual files.

‘%1.f’ comes from the WARN, not me; it isn’t there in the files.

I feel as though this is something really, really stupid, but I can’t see what it is :frowning:

and I did say you’d probably want some

I don’t see where your Item has picked up some unsuitable default format, but that appears to be the problem.