Java.lang.number error in log

Hi I believe i have a similar problem to this https://community.openhab.org/t/openhab-rule-java-lang-number-problem/30734/4 but I can’t work out how to fix it I have a rule for presence detection copied from another user. Unfortunately i havent been successful in contacting the original author of the rule script for a solution.
The error I get is

Error during the execution of rule Wifi Detection: java.lang.Number

the rules in use are

rule "Wifi Detection"
	when
		Time cron "30 * * * * ?"
	then
		var Number now_ms = now.millis
		var Number Person_1_Wifi_LastSeen_Millis = (Person_1_Wifi_LastSeen_Seconds.state as Number) * 1000
		var Number Person_2_Wifi_LastSeen_Millis = (Person_2_Wifi_LastSeen_Seconds.state as Number) * 1000

		logInfo("Wifi Detection", "Millis since last seen P1: "+(now_ms - Person_1_Wifi_LastSeen_Millis))
		logInfo("Wifi Detection", "Millis since last seen P2: "+(now_ms - Person_2_Wifi_LastSeen_Millis))

		if ( (now_ms - Person_1_Wifi_LastSeen_Millis) > 4*60*1000 ) {
			logInfo("Wifi Detection", "Person_1 not here")
			Person_1_Wifi.setState(OFF)
		}

		if ( (now_ms - Person_2_Wifi_LastSeen_Millis) > 4*60*1000 ) {
			logInfo("Wifi Detection", "Person_2 not here")
			Person_2_Wifi.setState(OFF)
		}
end
rule "Wifi Detection Person_1"
	when
		Item Person_1_Wifi_LastSeen_Seconds received update
	then
		var Number now_ms = now.millis
		var Number Person_1_Wifi_LastSeen_Millis = (Person_1_Wifi_LastSeen_Seconds.state as Number) * 1000

		logInfo("Wifi Detection", "Millis since last seen P1: "+(now_ms - Person_1_Wifi_LastSeen_Millis))

		if ( (now_ms - Person_1_Wifi_LastSeen_Millis) < 4*60*1000 ) {
			logInfo("Wifi Detection", "Person_1 still here")
			Person_1_Wifi.setState(ON)
		}
end
rule "Wifi Detection Person_2"
	when
		Item Person_2_Wifi_LastSeen_Seconds received update
	then
		var Number now_ms = now.millis
		var Number Person_2_Wifi_LastSeen_Millis = (Person_2_Wifi_LastSeen_Seconds.state as Number) * 1000

		logInfo("Wifi Detection", "Millis since last seen P2: "+(now_ms - Person_2_Wifi_LastSeen_Millis))

		if ( (now_ms - Person_2_Wifi_LastSeen_Millis) < 4*60*1000 ) {
			logInfo("Wifi Detection", "Person_2 still here")
			Person_2_Wifi.setState(ON)
		}
end

rule "Wifi Event Person_1"
	when
		Item Person_1_Wifi_Event received update
	then
		if ( Person_1_Wifi_Event.state == ON ) {
			logInfo("Wifi Detection", "Person_1 came home (Wifi Event)")
			Person_1_Wifi.setState(ON)
		}
		if ( Person_1_Wifi_Event.state == OFF ) {
			logInfo("Wifi Detection", "Person_1 left (Wifi Event)")
			Person_1_Wifi.setState(OFF)
		}
end
rule "Wifi Event Person_2"
	when
		Item Person_2_Wifi_Event received update
	then
		if ( Person_2_Wifi_Event.state == ON ) {
			logInfo("Wifi Detection", "Person_2 came home (Wifi Event)")
			Person_2_Wifi.setState(ON)
		}
		if ( Person_2_Wifi_Event.state == OFF ) {
			logInfo("Wifi Detection", "Person_2 left (Wifi Event)")
			Person_2_Wifi.setState(OFF)
		}
end

All my items have a status of NULL, and I understand that they are in uninitialised state but how do I change this if this is the problem.
This is the link for the original authors work.
https://github.com/dersimn/OpenWRT-Presence-Detector-over-MQTT

Thanks in advance

Tim

  • In a System started rule sendCommand or postUpdate an initial value to the Items

  • Add checks to the code to test whether the Item’s state is NULL before blindly trying to cast it to Number

var Number Person_1_Wifi_LastSeen_Millis = if(Person_1_Wifi_LastSeen_Seconds.state == NULL) -1 else (Person_1_Wifi_LastSeen_Seconds.state as Number_ * 1000
2 Likes

Thanks Rich I added your line to the code and its definitely improved my problem however i now get errors in the log

2017-07-31 17:25:30.038 [INFO ] [marthome.model.script.Wifi Detection] - Millis since last seen P1: 1501518330015
2017-07-31 17:25:30.047 [INFO ] [marthome.model.script.Wifi Detection] - Millis since last seen P2: 1501518330015
2017-07-31 17:25:30.062 [INFO ] [marthome.model.script.Wifi Detection] - Person_1 not here
2017-07-31 17:25:30.067 [ERROR] [rthome.core.library.items.SwitchItem] - Tried to set invalid state 0 on item Person_1 of type SwitchItem, ignoring it
2017-07-31 17:25:30.069 [ERROR] [rthome.core.library.items.SwitchItem] - Tried to set invalid state 0 on item Presence of type SwitchItem, ignoring it
2017-07-31 17:25:30.085 [INFO ] [marthome.model.script.Wifi Detection] - Person_2 not here
2017-07-31 17:25:30.089 [ERROR] [rthome.core.library.items.SwitchItem] - Tried to set invalid state 0 on item Person_2 of type SwitchItem, ignoring it
2017-07-31 17:25:30.091 [ERROR] [rthome.core.library.items.SwitchItem] - Tried to set invalid state 0 on item Presence of type SwitchItem, ignoring it

Tim

Do you have some other code that refers to a Person_1 Item? There is no reference to such an Item in the above code and the error is caused by trying to sendCommand or postUpdate or set the state of a Switch Item with the value 1.

Also, now that I see the code above a little more closely, you should absolutely NOT be using setState to change the state of an Item.

If you want to command something to do something you use sendCommand. If you want to just change an Item’s state without what ever is linked to that Item performing an action you use postUpdate.

Ok so what I have is an openwrt router acting as a mqtt client and sending who is present and how many seconds since last seen to a mosquitto server on a Raspberry pi on which openhab is located. I can see in the mosquitto log theMAC address of the present persons phone and this is used by openhab items like this

Group:Switch:SUM Presence "People at home: [%d]" <presence>
  Group:Switch:MAX Person_1 "Tim  [%d]" <man> (Presence)
    Switch Person_1_Wifi "Tim  Wifi [%s]" (Person_1)
  Group:Switch:MAX Person_2 "Kat [%d]" <woman> (Presence)
  	Switch Person_2_Wifi "Kat Wifi [%s]" (Person_2)

DateTime Person_1_Wifi_LastSeen         "Tim Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt="<[mosquitto:/presence/wifi/ac-*-*-*-*-*:state:default]" }
Number   Person_1_Wifi_LastSeen_Seconds "Tim Wifi last seen [%d]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/seconds:state:default]" }
DateTime Person_2_Wifi_LastSeen         "Kat Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*:state:default]" }
Number   Person_2_Wifi_LastSeen_Seconds "Kat Wifi last seen [%d]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/seconds:state:default]" }

Switch   Person_1_Wifi_Event            "Tim Wifi Event [%s]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/event:state:MAP(presence_event.map)]" }
Switch   Person_2_Wifi_Event            "Kat Wifi Event [%s]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/event:state:MAP(presence_event.map)]" }

i have a transform to change what openwrt sends

new=ON
del=OFF

and i have a sitemap like this

sitemap default label="Harrison's Home" {
  
   Frame label="Today" {
        Text item=Date

   }
   
   Frame label="Presence" {
        Switch item=Presence
        Switch item=Person_1
        Text item=Person_1_Wifi_LastSeen
        Switch item=Person_2
        Text item=Person_2_Wifi_LastSeen        
 
   } 

   Frame label="Dining room" {
        Group item=DSPW215_group

   }
    
}

other than this and the rule above i have nothing else in place.

with regards the rule i should change all the setstate to sendcommand then ?

I think the error you are seeing is because MAX makes no sense as the aggregation for a Switch. I suspect SUM will also generate errors.

A Switch can only be ON or OFF, it can’t be a number and MAX and SUM return a Number. If you want Presence to be the number of its members that are on you MIGHT be able to make it work with:

Group:Number:SUM Presence
Group:Number:MAX Person_1

However, I don’t know if that is guaranteed to work. I don’t know how the OH internals will treat the ON/OFF switch states when doing the addition and comparisons. If that doesn’t work then you will need to do the math part in a Rule and change your Group definitions to something like:

Group:Switch:OR(ON,OFF) Presence
Group:Switch:OF(ON,OFF) Person_1

Based on how you are using it on your sitemap (i.e. as a Switch) the latter is more appropriate.

You should only use sendCommand or postUpdate in rules. You should never use setState.

Looking at the Rule more closely, it seems overly complex. There are a lot of features built into OH and other bindings and Rules features that would make this much simpler.

Questions:

  • how frequently does openwrt report who is present? From a quick glance at the script’s readme it looks like once per minute but don’t know for sure.

  • Use a lamba or at least merge Person_1 and Person_2 rules. Don’t Repeat Yourself

  • Use the Expire binding or a Timer to determine when a person is gone rather than a rule that fires every 30 seconds

  • Use now’s and DateTimeType’s methods to do time comparisons and such rather than converting to msec and back.

Items:

Group:Switch:OR(ON,OFF) Presence "Some [MAP(present.map):%s] Present" <presence>
Group:Switch:OR(ON,OFF) Person_1 "Tim [MAP(present.map):%s] Present" <man> (Presence)
Group:Switch:OR(ON,OFF) Person_2 "Kat [MAP(present.map):%s] Present" <woman> (Presence)

Switch Person_1_Wifi_Event "Tim Wifi" (Person_1) { mqtt=..., expire="4m,state=OFF" } // turns OFF 4 minutes after last time it is set ON
Switch Person_2_Wifi_Event "Kat Wifi" (Person_2) { mqtt=..., expier="4m,state=OFF" } // turns OFF 4 minutes after last time it is set ON

DateTime Person_1_Wifi_LastSeen "Tim Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt=... }
DateTime Person_2_Wifi_LastSeen "Kat Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt=... }

present.map:

ON=is
OFF=is not

sitemap:

Unchanged.

rules:
No rules necessary. If you want to have some logs when people come or go:

rule "Someone's presence changed"
when
    Item Presence changed
then
    if(Presence.state == ON) logInfo("presence", "Someone came home")
    else logInfo("presence", "Everyone is gone"
end

rule "Someone's presence changed"
when
    Item Person_1 changed or
    Item Person_2 changed
then
    logInfo("presence", "Tim is now " + if(Person_1.state == ON) "home" else "away"
    logInfo("presence", "Kat is now " + if(Person_2.state == ON) "home" else "away"
end

You don’t need “Wifi Detection” rule because the Expire binding will set the Wifi presence switch to OFF automatically after 4 minutes of not receiving an update from the router.

You don’t need the “Wifi Detection Person_X” rules because the Person_1_Wifi Item is already being turned ON by the router’s script.

You don’t need to keep the Wifi and Wifi_Event Items separate. Just let the Wifi_Event Item serve to repesent when the router detects the device. Then let the Group functions aggregate the states of the sensors.

1 Like

Wow what an answer!
thanks Rich i cant believe how much more simple/condensed it all is now
Ive installed the expire binding and input all the alterations you suggested. You are correct that the router pings a message every minute and I can subscribe to that message on the Pi to confirm I’m receiving it.
Another error has evolved regarding the Transform.

2017-07-31 21:41:37.563 [WARN ] [.core.transform.TransformationHelper] - Cannot get service reference for transformation service of type MAP
2017-07-31 21:41:37.564 [WARN ] [ui.internal.items.ItemUIRegistryImpl] - couldn't transform value in label because transformationService of type 'MAP' is unavailable

I don’t think my items are being updated with the Mqtt messages
If I subscribe to all topics on mosquito I get messages

{/presence/wifi/}*-*-*-*-*-*/event del

If my phone disconnects from WiFi or event new if it connects.

And

{/presence/wifi}*-*-*-*-*-* 2017-07-31T22:17:00.000+0100

For last seen update

And my items show

{ mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/event:state:MAP(presence_event.map)]" }

And

{ mqtt="<[mosquitto:/presence/wifi/ac-*-*-*-*-*:state:default]" }

You need to install the MAP transform.

Without that transform your event Items will not be able to process the messages and your Item labels won’t work.

1 Like

So this is the update I had MAP Transform installed already for the previous item setup. A quick re-install sorted that error.
The rules that you wrote for me were missing a few ‘)’ brackets so that sorted another error in log.
I removed the { and } brackets from the script on the router so that it matched my item config and now i see the last seen (date)update on Basic UI.
my items now look like this

Group:Switch:OR(ON,OFF) Presence "Someone [MAP(present.map):%s] Present" <presence>
Group:Switch:OR(ON,OFF) Person_1 "Tim [MAP(present.map):%s] Present" <man> (Presence)
Group:Switch:OR(ON,OFF) Person_2 "Kat [MAP(present.map):%s] Present" <woman> (Presence)

Switch Person_1_Wifi_Event "Tim Wifi" (Person_1) { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*/event:state:MAP(presence_event.map)]", expire="4m,state=OFF" }

Switch Person_2_Wifi_Event "Kat Wifi" (Person_2) { mqtt="<[mosquitto:/presence/wifi/)*-*-*-*-*-*/event:state:MAP(presence_event.map)]", expire="4m,state=OFF" }

DateTime Person_1_Wifi_LastSeen "Tim Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*:state:default]" }

DateTime Person_2_Wifi_LastSeen "Kat Wifi last seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" { mqtt="<[mosquitto:/presence/wifi/*-*-*-*-*-*:state:default]" }

However 2 problems I have are:

  1. The icon’s for man ,women and presence wont show for some reason i have it set as ‘svg’ in org.eclipse.smarthome.basicui.cfg

2)I get this error

2017-08-01 20:21:02.122 [WARN ] [rm.AbstractFileTransformationService] - Could not transform '-' with the file 'present.map' : Target value not found in map for '-'

the messages come through as

/presence/wifi/*-*-*-*-*-* 2017-07-31T22:17:00.000+0100

and

/presence/wifi/*-*-*-*-*-*/event del       (0r new)

is it the ‘-’ between the MAC address it doesnt understand ?
when i put a transform in to change ‘-’ to anything else it places the new symbol before the switches on my Basic UI but the switches still wont operate when an event happens.

Cancel the first question my items use a Classic icon set and therefore ‘man’ has to be ‘man_1’
‘women’ = ‘women_1’
‘presence’=‘present’

Problem 2 has to do with how OH handles Undefined Items. When an Item is first created it lacks a state. This is called Undefined and you can test for this in Rules using if(MyItem.state == NULL).

On the sitemap, Items that are undefined will show up as -. And the error is complaining because present.map doesn’t have a mapping for - so it doesn’t know how to transform the label. Add the following to present.map:

-=is unknown to be

Remember that present.map is only being used for your Item’s labels. Transforming the MQTT messages is handled by presence_event.map. So the error is strictly to do with the label, not processing the MQTT messages.

One other thing, you probably want to put the the presence Items on your sitemap as Text rather than Switch since the Items are meant to be informational (i.e. you won’t be turning on or off presence for anyone manually).

I am troubled that the screenshot of the sitemap you provided do not show the full label, but I think that may be caused by the missing entry in the map file and the error you are seeing.

Ok so by adding that to present.map I get no errors in log however the basic UI still doesnt change the switch

now this is what I see

with regard the presence item so you mean change

sitemap default label="Harrison's Home" {

   Frame label="Today" {
        Text item=Date

   }

   Frame label="Presence" {
        Text item=Presence
        Switch item=Person_1
        Text item=Person_1_Wifi_LastSeen
        Switch item=Person_2
        Text item=Person_2_Wifi_LastSeen

   }

   Frame label="Dining room" {
        Group item=DSPW215_group

   }

}

That is because the items remain Uninitialized.

Aside: I notice that the "Present part is missing from the label. You may need to modify the Item’s label to put the “Present” inside the [ ].

Since you are not seeing any errors in the logs it probably means you are not receiving any event messages to turn these switches on or off in the first place. Until they receive and successfully parse an event message the Switches will remain Undefined.

Also change Person_1 and Person_2 to Text.

so the Goood news is you were right even though i changed the script in the router to not include the {} brackets it needed a reboot to implement the change this in turn showed the sitemap as such


when i changed the item file so that present was included in the ] like so

Group:Switch:OR(ON,OFF) Presence "Someone [MAP(present.map):%s Present]" <present>
Group:Switch:OR(ON,OFF) Person_1 "Tim [MAP(present.map):%s Present]" <man_3> (Presence)
Group:Switch:OR(ON,OFF) Person_2 "Kat [MAP(present.map):%s Present]" <woman_3> (Presence)

and the sitemap to Text it does nothing

If I add present to the Transform I get the required effect

one problem Ive noticed is that my router scripts only update last seen every minute. The event script is only sent should my wifi connect or disconnect. However the 4 min expire is turning the presence off as no event happens and my phone is still here so no script is sent.

Any thoughts?

Ok, this is different behavior than expected which might require a rule.

It might not.

First of all, is it possible to update the php script to report the event every minute instead of just when the phone goes online or offline?

Is last seen published even when the phone is no longer connected? If it stops when the phone is disconnected we can use those messages to drive the switches instead of the events.

Do you always get a disconnect event when the phone goes away? If so we can use the events and do away with the timers, or change slightly how we use the timer.

Ok so the last seen scipt is run by a cronjob that starts every minute, The event script is placed in the RC Local file with a nohup command so as far as I understand, it runs continuously and sends the mqtt message when a phone disconnects or connects.

The phones becomes an ‘associated station’ on the router which in theory means that as long as the phone doesnt disconnect from wifi it should show as present no matter how long you leave the phone (sleep mode) however I have noticed that the wife’s iphone does disconnect when sleeping but so far my android has not( I will be changing her phone for an android soon so hopefully this wont be a problem).

The last seen script only sends the date,time and MAC addresses for any associated stations hence why i have to specify the MAC addresses i want receive updates for in my items. (namely my wife’s and my phone )
so if the phone disconnects it wont send the message for that MAC address.

The only problem with using this as the trigger is that it sometimes takes several minutes before the device become disassociated but this is still an option however once again it will be a problem with the iphone.

So far with my phone at least I have had accurate disconnect events and as far as ive seen so far i do not disconnect or become disassociated when my phone is idle.

As I only have the date and time and a power socket working on my openhab I havent left my openhab running as I wanted a presence detection working before I left it running continuously. So I havent got any logs to show whether my phone has 100% no disconnects or disasociations using the mqtt messages . The logs on my router are minimal and only really show when a handshake is performed between devices and that the last seen script is run. Its only by viewing the routers admin page that I see my wifes phone disconnect when idle or that my phone appears to never disconnect.

Maybe I should leave openhab running and at least this will show me if my theory is correct.

Good luck with that. I tried to do that once… :wink:

Good. We can use that. Add the following to your Person_x Items:

<[mosquitto:/presence/wifi/*-*-*-*-*-*:state:ON]

So every time the router sends a LastSeen message it will update the Switch Item to ON. since that happens every minute it will keep the expire binding from changing the Switch to OFF. 4 minutes after the last LastSeen message (if for some reason the disconnected event didn’t get sent) the Switch will go OFF.

This will be a problem no matter what I suspect.

Detecting iPhones on the network is a well known and difficult problem. When it goes to sleep it puts the device into a hibernation mode that makes it mostly unresponsive to network events. However, if you search the forum for “hping” you will see one way a lot of people have got around this problem with iPhones. The Network binding just added and arping feature that essentially does the same as the hping solution.

Personally, I use a combination of presence sensors in my system. I configured my and my wife’s phones with static IPs on the router. Then I use the Network binding to periodically ping them to see if they are present.

But the iPhone disconnects so I also use Bluetooth detection on a number of Raspberry Pis that I already have scattered throughout the house for other purposes using a script I wrote. Finally, I’ve added reelyActive to my Raspberry Pi 3 which also does BT device presence detection but in a smarter way. I’ve since replaced one of my old Pi 1s with a Pi Zero W so plan on adding reelyActive to that one as well and see if I can start to get some better resolution (e.g. tell which floor the device is on). That is a relatively low-level priority though.

BT works well for me because both my wife and I have a smart watch and my wife has a medical device always attached which also uses BT so it works well.

Anyway, I require at least two sensors to report a device as present to mark a person as present (BT can have false positives).

1 Like

Good luck with that. I tried to do that once… :wink:
Tell me about it :laughing:

I’ll have to do a bit of research on here about this arping solution with the network binding sounds like this will help with the accuracy of my presence detection.

I’ve also thought about Bluetooth as an option especially using reelyactive and I like the idea of using multiple sensors to attack the presence accuracy from different directions. I assume you have mentioned this in another thread. I’ll have to have a look into the things you’ve mentioned and try and implement it into my system.

Out of interest how close to 100% accurate is your setup, do you still get the occasional false presence or false away event ?

Thanks for all your help in getting theses problems with my presence setup sorted I’ll shall add that addition to my items and hopefully incorporate your other ideas.