How to find out type of variable

Hello @all,

I use a function inside my rule. For this function I provide an object variable (called SV) that can be a Numer or a String. This is used to control my rollershutters. So this var can be “UP”, “DOWN”, 10, 20,…etc.
Generally, this works fine.
But wow to find out inside the function what kind of variable was transfered. Sounds very easy, but I didn´t got it.

If found this code, but this doesn´t work:

if(SV instanceof DecimalType) {}

Any ideas?
Thanks very much.

https://docs.openhab.org/concepts/items.html#a-note-on-items-which-accept-multiple-state-data-types

Hmmmm…yes, but this is no answer regarding my question.
I want to find out the Type of a variable.

rule "SS"
when
	System started or
	Item rs_AZ changed
then
        logInfo("_",rs_AZ.state.toString)
	if     (rs_AZ.state instanceof PercentType) {logInfo("_","PercentType")}
	else if(rs_AZ.state instanceof UpDownType) {logInfo("_","UpDownType")}
end
2018-01-16 14:37:01.872 [INFO ] [org.eclipse.smarthome.model.script._] - NULL
2018-01-16 14:42:58.781 [INFO ] [org.eclipse.smarthome.model.script._] - 100
2018-01-16 14:42:58.786 [INFO ] [org.eclipse.smarthome.model.script._] - PercentType
2018-01-16 14:43:33.647 [INFO ] [org.eclipse.smarthome.model.script._] - 45
2018-01-16 14:43:33.650 [INFO ] [org.eclipse.smarthome.model.script._] - PercentType
2018-01-16 14:43:34.838 [INFO ] [org.eclipse.smarthome.model.script._] - 0
2018-01-16 14:43:34.852 [INFO ] [org.eclipse.smarthome.model.script._] - PercentType

Thanks Harry,
but still not working for me.

I don´t have an item, I want to identify the type of a variable.
And I don´t have any ideas, why instanceof is not working.

	var x = aa_aktiv.state
	if     (x instanceof OnOffType  ) {logInfo("_","1:OOT")}
	else if(x instanceof PercentType) {logInfo("_","1:PT")}
	else if(x instanceof UpDownType ) {logInfo("_","1:UDT")}
	x = rs_AZ.state
	if     (x instanceof OnOffType  ) {logInfo("_","2:OOT")}
	else if(x instanceof PercentType) {logInfo("_","2:PT")}
	else if(x instanceof UpDownType ) {logInfo("_","2:UDT")}
	x = UP
	if     (x instanceof OnOffType  ) {logInfo("_","3:OOT")}
	else if(x instanceof PercentType) {logInfo("_","3:PT")}
	else if(x instanceof UpDownType ) {logInfo("_","3:UDT")}
2018-01-16 15:19:04.105 [INFO ] [org.eclipse.smarthome.model.script._] - 1:OOT
2018-01-16 15:19:04.111 [INFO ] [org.eclipse.smarthome.model.script._] - 2:PT
2018-01-16 15:19:04.114 [INFO ] [org.eclipse.smarthome.model.script._] - 3:UDT

Here is my code, that doesn´t work.

val Functions.Function1<Object,Boolean> f_test = [ SV |
                                                                                                                                                                                                                   
    logInfo("test","Test Start")
    if(SV instanceof DecimalType) logInfo("test","Number")
    if(SV instanceof StringType) logInfo("test","String")
                                                                                                                                                                                                                
    logInfo("test","Instance:"+test)
    logInfo("test","Item:"+SV)
                                                                                                                                                                                                                   
return true                                                                                                                                                                                                        
]                                                                                                                                                                                                                  
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
rule "test"
when Item test changed
then
                                                                                                                                                                                                                   
f_test.apply(10)
f_test.apply("Test")
                                                                                                                                                                                                                   
end

It’s easyer to see the whole code.
In youreExample it’s always a object.
What is the reason for the instanceof-test?
Is it only for the output, then ever use toString.
Else you have to solve it in a different way.

val Functions.Function1<Object,Boolean> f_test = [ SV |
//  logInfo("test","Test Start")
    logInfo("test",SV.toString)
    if(SV instanceof Object) logInfo("test","Object:")
    if(SV instanceof DecimalType) logInfo("test","Number:")
    if(SV instanceof StringType) logInfo("test","String:")
    var x = SV
    if(x instanceof Object) logInfo("test","Object:")
    if(x instanceof DecimalType) logInfo("test","Number:")
    if(x instanceof StringType) logInfo("test","String:")
//  logInfo("test","Instance:"+test) ???
//    logInfo("test",SV.toString)
return true]                                                                                                                                                                                                                  

rule "test"
when
	System started
then
	f_test.apply(10)
	f_test.apply("Test")
end
2018-01-16 15:48:35.431 [INFO ] [.eclipse.smarthome.model.script.test] - 10
2018-01-16 15:48:35.435 [INFO ] [.eclipse.smarthome.model.script.test] - Object:
2018-01-16 15:48:35.440 [INFO ] [.eclipse.smarthome.model.script.test] - Object:
2018-01-16 15:48:35.445 [INFO ] [.eclipse.smarthome.model.script.test] - Test
2018-01-16 15:48:35.449 [INFO ] [.eclipse.smarthome.model.script.test] - Object:
2018-01-16 15:48:35.453 [INFO ] [.eclipse.smarthome.model.script.test] - Object:

Thanks Harry,

ok, I see the instanceof is not the right way.
I need to know, what is inside my Object.

  • String
    or
  • Number

Depending on that, my script goes different ways.

    if     (SV == NULL)             logInfo("test"," null")
    else if(SV == UP || SV == DOWN) logInfo("test"," up/down")
    else   			    logInfo("test"," else")

The problem you had with instanceof is that DecimalType and StringType are OH State Types. You are passing generic Java Types. So what you would want is

if(SV instanceof Number) logInfo('test", "Number")
else if(SV instanceof String) logInfo("test", "String")

But, as Harry indicates, just use String and send “UP”, “DOWN”, “10”, “20”, etc. Unless you have to do math there is no reason to pass anything but a String to your lambda.

Do you need to do math if the value is a number or are you just passing it on?

1 Like

Great. That´s it.
Thanks Rich.

My script is a little bit more than shown here. I want to distinguish between presets and variable inputs for my rollershutters.
So I need a characteristic to switch between theese both possibilities.

Thank you all for your helb.

Coming a bit late to the party, but for anyone else who ends up where with the question, how to find out the type of a variable, here’s the answer:

variable.getClass.getSimpleName

This will get you the class name of the object variable. You’d usually want the simplified name without the package info.

Tried to use that in OH3.2, any idea what import I am missing ?

2022-01-15 09:20:50.304 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'testit-1' failed: cannot invoke method public final native java.lang.Class java.lang.Object.getClass() on null in testit

I am looking to use this to determine if a variable contents matches a type definition.

I am searching after a nasty problem with rules DSL and UoM where an item is of Number:Power. Item’s value was set with UoM but it’s losing its UoM somewhere during the persistence process so when I access with typecast like item.state as QuantityType<Power> I’m getting the error below.

Script execution of rule with UID 'Energiemanagement-38' failed: Could not cast 0.0 to org.openhab.core.library.types.QuantityType; line 2481, column 72, length 58 in Energiemanagement javax.script.ScriptException: Could not cast 0.0 to org.openhab.core.library.types.QuantityType; line 2481, column 72, length 58 in Energiemanagement

This is in Rules DSL, right?

You can use instanceof along the lines of

if(myItem.state instanceof QuantityType)

There are similar operations in ECMAScript, Jython, etc.

But Jake’s solution should work too, it at least not generate an exception like that.

Yes rules DSL. To fix the exception, the interesting question I’m after is:
would instanceof return true if the variable has UoM and false when it has not ?
ATM I’m struggling in testing to recreate the situation with the item having no UoM, as I said I don’t know exactly when and how that happens.
Or any other idea for a proper test for that condition.

Not quite, since Number variables can have units and QuantityTypes can have no visible units.

I think you would need to test for presence of non-numeric characters in a string version.

As rossko57 says, it would potbelly have to be a two part test. Dust test to see if it’s a QuantityType. DecimalTypes don’t carry units.

Then test of the QuantityType had units. But you can do that by calling 'qt.gerUnit()` I think if you didn’t want to resort to string parsing.

Persistence always loses the UoM, it has to reconstruct it. It uses the Item metadata pattern to do that.

Did it just happen to retrieve zero that time, or do you think that might be more than a coincidence?

metadata, really ? So if I do not enter any metadata for an item it does not know the default UoM ?
Or do you mean the item type (which strictly speaking isn’t meta) ?
pattern metadata is just used for displaying

No I’ve encountered that multiple times, with multiple items, across restarts even.