openhab / openhab-android

openHAB client for Android
https://play.google.com/store/apps/details?id=org.openhab.habdroid
Eclipse Public License 2.0
599 stars 317 forks source link

UI with single widget refreshes itself every 30 seconds #460

Closed AndreaRicci94 closed 6 years ago

AndreaRicci94 commented 6 years ago

Hi all,

I am currently experimenting with openHAB for Android (or HABdroid, if you want) and a sitemap in which I have a Webview widget which displays a PHP page built by me hosted in one of my servers. The Webview is configured to take pretty much all of the space available in the phone screen because in this interface I am building that is the main component (the webpage serves as a MPD controller and file browser).

Because of that need, the user moves around inside the webpage, and maybe changes its address according to what he needs to do.

Now the problem: I have noticed HABdroid refreshes the entire UI every 30 seconds, hence "re-drawing" the Webview component which also starts over from the original address as specified in the sitemap file. This is annoying for me, because it means the user cannot "move freely" inside the Webview component and maybe change pages over minutes of browsing (he would be redirected to the original address after 30 seconds from first load).

Please note: I don't know if this is an issue for you, but I would like some insight as of why this behavior is implemented this way, as well as a way to disable it if possible. I had a look at the application source code but, given that I am not very much skilled in Java programming I did not find anything useful about this.

Thank you all for your time and patience. Have a good day.

Andrea

mueller-ma commented 6 years ago

Hey Andrea, can you check if the php session variable is reset every 30s? Otherwise you could save the current path in it and redirect to that path if the user accesses the main page.

AndreaRicci94 commented 6 years ago

Hey there,

Thank you for your input. I actually tested what you asked for and I can confirm the $_SESSION variable is not unset every 30 seconds, so I might use that as my last resort.

However, I was still hoping you all could give me some insight on how to disable this behavior in some way... I need to consider this is only one way for me to use the Webview item: I have some other ideas in mind in which the webpage refreshes its contents via AJAX so having the app UI reloading automatically would not be that good.

If you have any suggestion or comment, I am all ears. Thank you!

mueller-ma commented 6 years ago

I'm wondering why you are using openhab at all if you just want to display a website. You also could use a browser or maybe have a look at habdroid, which is quite customizable.

AndreaRicci94 commented 6 years ago

I am using openHAB because I have built a KNX system in the house, so the sitemap contains all the light switches, roller shutters, gate openers, alarm controllers and more.

Now the goal is to be able to manage my own-built multiroom music system: I have a Windows PC which, apart from the openHAB server, also handles music playback via MPD/MPC. The webpages I have built control this system and I want them to be integrated in the openHAB application currently in use in our Android smartphones.

My hope is to be able to use only openHAB for all the "smart appliances" I have in the house, including this multiroom audio system which is not branded (not Sonos, Logitech or the like). I do not use MPD binding with openHAB because I find it incomplete for my needs (I need a music file browser, and an enhanced playback support per zone/room).

That is why I'd rather stick to openHAB and not add another application for just this task (also with the need to explain another functioning method to the family members).

mueller-ma commented 6 years ago

Synchronous multi-room audio player: https://github.com/badaix/snapcast

AndreaRicci94 commented 6 years ago

That is not stable for Windows as of now because of https://github.com/badaix/snapcast/issues/24

Although I appreciate your efforts to suggest other methods (I think, if no other solutions are available, I will stick to the $_SESSION one), can we please return to the main focus?

Is there any way, even in the code if you suggest where to look, to disable this 30 seconds UI auto update?

lolodomo commented 6 years ago

@digitaldan @mueller-ma could you confirm the existence of this 30s auto-refresh and explain why it is required ?

AndreaRicci94 commented 6 years ago

I second that request. @digitaldan @mueller-ma Would you be so kind to advise on why this feature is implemented and if there is a way we can disable it?

I did some real-world testing with the $_SESSION variable and it is practically unuseable. In my case scenario, that refresh is really a pain.

mueller-ma commented 6 years ago

Sry, I have no idea if, why and how it is implemented this way. That was done a long time before I started contributing to openhab.android.

lolodomo commented 6 years ago

With the current implementation without the handling of SSE, I think few things would be not refreshed without this auto-refresh. That is probably the reason why it was introduced. By the way, we should think about a move to SSE to have a reliable and efficient update mechanism but that's another history.

lolodomo commented 6 years ago

In fact, the 30s refresh is not harcoded in the app but is the result of the long polling HTTP request on the sitemap REST API which send an update every 30 seconds for each displayed page (main page and sub-page). The timeout of the long polling HTTP request is in fact set to 5 minutes in the app. So it looks like more something to investiguate in the sitemap REST API.

lolodomo commented 6 years ago

At the same time, I can see on server side coming requests every 30 seconds:

18:27:25.051 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/0002'
18:27:25.061 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/maison_test'
18:27:25.184 [INFO ] [smarthome.event.ItemStateChangedEvent] - Date changed from 2017-12-02T18:26:25.157+0100 to 2017-12-02T18:27:25.163+0100
18:27:25.203 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/0002'
18:27:25.348 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/maison_test'
18:27:55.929 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/0002'
18:27:55.954 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/maison_test'
18:28:25.199 [INFO ] [smarthome.event.ItemStateChangedEvent] - Date changed from 2017-12-02T18:27:25.163+0100 to 2017-12-02T18:28:25.168+0100
18:28:26.621 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/0002'
18:28:26.693 [DEBUG] [rest.sitemap.internal.SitemapResource] - Received HTTP GET request at 'sitemaps/maison_test/maison_test'

Does the long polling mechanism imply the request being re-sent every 30 seconds ? I am lost...

lolodomo commented 6 years ago

I am so stupid. The 30s timeout is on the server side (REST API): https://github.com/eclipse/smarthome/blob/master/bundles/io/org.eclipse.smarthome.io.rest.sitemap/src/main/java/org/eclipse/smarthome/io/rest/sitemap/internal/SitemapResource.java#L580 The request is blocked by the server at a maximum of 30 seconds and then it returns the page data: https://github.com/eclipse/smarthome/blob/master/bundles/io/org.eclipse.smarthome.io.rest.sitemap/src/main/java/org/eclipse/smarthome/io/rest/sitemap/internal/SitemapResource.java#L217

The solution I imagine is that the REST API should return something that tells the caller that the timeout expired. In this case, the UI will just recall the HTTP request. Or we could simply disable this timeout.

digitaldan commented 6 years ago

SSE is the right solution , we just have not had any volunteers to port the android or iOS application to use it, would be a welcome contribution !

AndreaRicci94 commented 6 years ago

Hi guys!

I have been following your discussion in the last several days, and I really appreciate it. Although, given that I needed to find a fix to my problem in order to continue with development, I looked more thoroughly at the code and I applied a very "quick and dirty" fix to solve the issue.

Unless you ask me to do so (but I seriously doubt it :P ) I am not going to make a PR for that, because this fix I think only applies in my case scenario.

Quick explanation: in my case when there is a Webview involved, only this very specific component is in the page and no other elements are involved (no switches, dimmers, selections or anything else). So, I had a look at the processContent(String responseString, boolean longPolling) method located in openhab.android/mobile/src/main/java/org/openhab/habdroid/ui/OpenHABWidgetListFragment.java and I edited the following:

Lines from 395 to 397 originally:

public void processContent(String responseString, boolean longPolling) {

Log.d(TAG, "processContent() " + this.displayPageUrl);

After the edit I made:

public void processContent(String responseString, boolean longPolling) { if (!openHABWidgetAdapter.isEmpty() && openHABWidgetAdapter.getItem(0).getType().equals("Webview")){ Log.d(TAG, "Execution of UI reload stopped because we have a Webview."); return; }

Log.d(TAG, "processContent() " + this.displayPageUrl);

Before you say anything: I know this is not the way to do it, but I did some testing and it seems that, every time there is a Webview as the first (zero) element in the elements collection, the refresh does not appear. In my case, as I have explained earlier in the post, that solves the issue. Other UI scenarios where we have switches and other things, everything is fine and states are updated accordingly.

I think, as a workaround and a cleaner solution, implement a setting in the menu like "Do not refresh UI with Webviews" and the code actually looking through openHABWidgetAdapter and not only the 0 index looking for webviews, this would be a nice response to the issue at hand.

Please do not throw rancid tomatoes at me! :-D :-D

lolodomo commented 6 years ago

@AndreaRicci94 : the 30 seconds refresh is a general problem in the app, we will not fix it only for the Webview but rather fix it globally. And there is no need for an option. It takes me time yesterday to understand where was the source of this refresh but it is now clearly identified and it is due to the way the long polling is handled by our REST API (blocking only 30 seconds). So the fix requires a change on the server side and probably a very little change in the Android app. I am volunteer to fix that globally.

lolodomo commented 6 years ago

@digitaldan : regarding the port to SSE, I am volunteer to have a try. This is certainly a big change and it will take time before I have something fully working. Don't expect anything before 2018. Until end of 2017, I will try to focus on little but annoying bugs.

lolodomo commented 6 years ago

I already propose a fix for the server side to be notified of the long polling reached timeout. https://github.com/eclipse/smarthome/pull/4673 Once this PR is merged, I will propose the corresponding change for the Android app.

maniac103 commented 6 years ago

You can do the app side change right now, you'll need to consider server versions without that field anyway ;-)

lolodomo commented 6 years ago

I have done a stupid mistake when fixing on the server side. A new fix is required on the server side.