Location stuff - GeoCode address, Distance etc

I think there is an open issue on this. Search the forum and github and you should find the discussion.

Thanks for your help on this. I have edited my original post with a setup that seems to be working, and hopefully covering all the points you mentioned. Particularly about using previousState.

Looking good but I still see two gotchas.

The following line will only be run when the .rule file is first loaded. It doesn’t run every time the rule is executed. Therefore is iPhoneThingStatus happens to be ONLINE when this .rules file is first loaded, it will remain ONLINE no matter what status the Thing changes to later on. And because it’s a val even if it did change status you couldn’t change the value of iPhoneThingStatus later anyway.

val iPhoneThingStatus = getThingStatusInfo("icloud:device:bc3dd7b8fb:3dfa568e").toString

To keep this in a global variable what you need to do is:

  • change val to var so iPhoneThingStatus can be updated after the .rules file is loaded
  • In rule “location_dad-Set OFFLINE” add a line to update iPhoneThingStatus with the current state, or just “OFFLINE” as all you really care about is whether it’s ONLINE or not, not the specific reason it’s offline.
  • Add another rule that triggers when the Thing changes to ONLINE and update iPhoneThingStatus to “ONLINE”

That will keep the variable iPhoneThingStatus in sync with the Thing’s actual status.

But there might be an easier way. This variable is only used in two rules and in one of them it’s just used in a log statement. So you can avoid the extra rule proposed above if you:

  • move the definition of iPhoneThingStatus to be the first line (after the log statement) in rule “location_dad-GEO”
  • In rule “location_dad-Set OFFLINE” change the log statement to just a hard coded message “iPhone is OFFLINE. Address set to OFFLINE”.

The second gotcha is in the some of the log statements. You postUpdate to MartinsiPhone_Address and then immediately read the state back on the next line in the log statement. E.g.

        MartinsiPhone_Address.postUpdate("OFFLINE")
        logInfo("Location - Dad", "iPhone is " + iPhoneThingStatus + ". Address set to " + MartinsiPhone_Address.state)

The gotcha here is MartinsiPhone_Address.postUpdate("OFFLINE") doesn’t happen instantaneously. In fact it can take quite some number of milliseconds to process. And it does that process in the background. OH doesn’t wait for MartinsiPhone_Address to actually update to “OFFLINE” before moving on to the next line of code. Consequently often you’ll be logging out the old state of MartinsiPhone_Address and not the one you just set it to because it hasn’t finished processing that update in the background yet.

The solution here is easy. You already know what you updated the Item to so just use that instead of trying to get the state back from the Item before the Item has finished processing the update.

logInfo("Location - Dad", "iPhone is " + iPhoneThingStatus + ". Address set to OFFLINE")

Except for these two gotchas which do need to be addressed, the code now is quite good and you should be proud of it. Thanks for posting and sticking it out with all the updates. I hope this will help you with future rules writing as well.

Thanks. :+1:

I took the easy way out.
Code updated in original post.

New question:

Is it possible to make something only trigger when the UI is actively open/being viewed?
I was thinking that the GeoCoding address only needs to run when someone is watching the UI. Reducing the API requests even more.

Different UI, same problem

in other words, no way to detect “just looking”.

However, all the UIs subscribe to updates events for display. There ought to be some horrible hack allowing detection of those subscriptions, allowing for “UI exists” rather than “in use”.

With OH3 new but as-yet rudimentary user management, it may be possible with some hack to detect user login. That’s a whole other topic and you might start a new topic for that.

Or perhaps do some lateral thinking - for example, some wall panels can detect when somebody is stood in front. Or you might know no-one will be looking if no-one is at home.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.