Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hue] Changed discovery to mDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client #11842

Merged
merged 7 commits into from
Oct 22, 2022

Conversation

cweitkamp
Copy link
Contributor

@cweitkamp cweitkamp commented Dec 22, 2021

  • Changed discovery to mDNS
  • Added HTTPS handling
  • Refactor HTTPClient to use Jetty shared client
  • Refactor to reduce code and simplify implementation

Depends on openhab/openhab-core#2622 and openhab/openhab-core#2635

Philips announced a brand new HUE API v2 being available. These are the first steps to add support for it.

The new API supports some really interesting new features like streaming SSEs. It uses HTTPS only. Additional, they will deprecate disable UPnP in Q2 2022 in favor of mDNS.

See their Migration Guide to new API.

Signed-off-by: Christoph Weitkamp github@christophweitkamp.de

@cweitkamp cweitkamp added enhancement An enhancement or new feature for an existing add-on work in progress A PR that is not yet ready to be merged awaiting other PR Depends on another PR labels Dec 22, 2021
@cweitkamp cweitkamp requested review from lolodomo and a team December 22, 2021 15:45
@cweitkamp cweitkamp added the additional testing preferred The change works for the pull request author. A test from someone else is preferred though. label Dec 22, 2021
@cweitkamp cweitkamp changed the title [WIP][hue] Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client [WIP][hue] Changed discovery to mDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client Dec 22, 2021
Comment on lines 709 to 713
// register trustmanager service
HueTlsTrustManagerProvider tlsTrustManagerProvider = new HueTlsTrustManagerProvider(
ip + ":" + hueBridgeConfig.getPort(), hueBridgeConfig.useSelfSignedCertificate());
serviceRegistration = FrameworkUtil.getBundle(getClass()).getBundleContext()
.registerService(TlsTrustManagerProvider.class.getName(), tlsTrustManagerProvider, null);
Copy link
Contributor Author

@cweitkamp cweitkamp Dec 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really ugly implementation and we do not want it. But unfortunately I did not yet found a better solution.

Implementing the HueTlsTrustManagerProvider to be a ThingHandlerService would be my favorite one but when doing so there will be a race condition between activation of the HueTlsTrustManagerProvider and initialization of the HueBridgeHandler.

Registering the HueTlsTrustManagerProvider in the HueThingHandlerFactory does not work because I need access to the configuration of the Thing to retrieve IP address, port and protocol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way for HueTlsTrustManagerProvider to return a status in the case that getting the external cert fails (i.e. the server is momentarily unreachable)? It seems like the current code has no provision to retry the cert retrieval process since it attempted only once during initialize().

@kaikreuzer
Copy link
Member

Wow, that's awesome, thank you - I already hoped that you would look into the new hue APIs! 😄
Especially the new SSE support is really nice to finally get instant state updates.

@cweitkamp
Copy link
Contributor Author

I am planning to separate the implementation into three steps. This is the first one.

  1. Basic refactoring
  2. Restore current behavior on v2 API - meaning new endpoints, new model - and keep v1 for users who own older Hue Bridges in the background
  3. Add handling of SSE

@cweitkamp cweitkamp force-pushed the feature-hue-v2-api branch 2 times, most recently from 95220ce to f4e3567 Compare December 23, 2021 10:26
@cweitkamp cweitkamp changed the title [WIP][hue] Changed discovery to mDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client [hue] Changed discovery to mDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client Dec 23, 2021
@cweitkamp cweitkamp removed the work in progress A PR that is not yet ready to be merged label Dec 23, 2021
@andrewfg
Copy link
Contributor

Continuing discussion with @lolodomo from this #11834 (comment)

So would make sense in case to set it to 0

You could still do that by means of an entry in the '.cfg' file (rather than via the UI).

My concern was just to keep the parameter for the hue binding.

@lolodomo the main reason to remove the parameter was the brilliant idea of @kaikreuzer quoted below. Which would enable new systems to pre-discover potential Things on the network without any bindings having been installed. However if you insist that it must be a binding parameter (instead of an entry in a .cfg file) then we could not develop such a great feature.

I would have loved for a long long time already to extract different UPnP+mDNS discovery services into an "installed by default" bundle, so that the setup wizard could directly identify devices in your home without the need of installing all the bindings first.)

@lolodomo
Copy link
Contributor

lolodomo commented Dec 23, 2021

My concern was to have a parameter, whatever the file in which to define it.

By the way, now that we move from UPnP to mDNS, is this grace period still useful for mDNS discovery?

@lolodomo
Copy link
Contributor

@cweitkamp : do you know if mDMD discovery is available for old v1 bridge?

@andrewfg
Copy link
Contributor

now that we move from UPnP to mDNS, is this grace period still useful for mDNS discovery?

I will install the JAR from this PR and test it on my Hue bridge to see if the mDNS disco suffers from the same problem as the UPNP disco.

BTW this time of year is a perfect time to test it. In my case the problem (on UPNP disco) only occurs when the Hue bridge is running "heavy" automations, and presumably the automation causes delays in sending the NOTIFY messages. This time of year is when I run a Christmas light colour loop in the front window of my house. This is quite a "heavy" automation.

@cweitkamp
Copy link
Contributor Author

@lolodomo I am afraid not.

mDNS is available Hue bridge v2.x (squared-shaped) and supported with firmware version 1.23 and beyond.

For older bridges there still is the HueBridgeNupnpDiscovery which retrieves results from https://discovery.meethue.com/. Both methods are recommended by Philips.

@andrewfg
Copy link
Contributor

I will install the JAR from this PR and test it on my Hue bridge

Unfortunately I could not build the binding jar because there is some dependency on PEMTrustManager in the core, which I cannot find. => So @cweitkamp could you please give me a link to the built JAR?

@cweitkamp
Copy link
Contributor Author

Here you are: org.openhab.core.io.net-3.3.0-SNAPSHOT.zip

@cweitkamp
Copy link
Contributor Author

How many concurrent connections can be made from shared Jetty client instance?

The client is configured to use at maximum 2 connections per destination. It uses 5 up to 10 threads. Those values are user specific (see https://github.com/openhab/openhab-core/blob/4096df1c6433f10e332632ced9f2e679dd8c340d/bundles/org.openhab.core.io.net/src/main/java/org/openhab/core/io/net/http/internal/WebClientFactoryImpl.java#L156-L163).

@andrewfg
Copy link
Contributor

Just to mention that HueTlsTrustManagerProvider.java would still need some work in order for it to support the certificate validation for SSE connections (as I have found in #13570 ) .. however I think that such work could be done in the latter PR rather than this one. And also I would need @cweitkamp to help me please :)

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

How many concurrent connections can be made from shared Jetty client instance?

The client is configured to use at maximum 2 connections per destination. It uses 5 up to 10 threads. Those values are user specific (see https://github.com/openhab/openhab-core/blob/4096df1c6433f10e332632ced9f2e679dd8c340d/bundles/org.openhab.core.io.net/src/main/java/org/openhab/core/io/net/http/internal/WebClientFactoryImpl.java#L156-L163).

Thanks. I will need to figure out how to add some more detailed logging when this happens, as it does happen consistently a few times per week now. It wouldn't be much of a problem if my rules were more well-written - currently I monitor all my devices and get push messages when they are offline/unreachable, but I don't consider if the reason is the bridge being offline, so that triggers a lot of messages. :-) It might be the number of threads being the limitation as some of my other bindings are quite busy all the time.

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

Just to report that I am also running the latest build, and I am NOT seeing any exceptions..

To see the exception, DEBUG log level would need to be set. Have your checked in logs if the bridge has come OFFLINE at any moment, even just for a few seconds? I'm suspecting (for me) if may be caused by activity from other bindings using the shared http client.

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

@lolodomo, @cweitkamp - although the switch to shared Jetty client has changed some behavior related to timeouts in my setup, I believe this is a general problem for which this binding is not to blame, probably it's just a symptom. So IMHO it would be okay to merge if no one else but me experienced any issues. I will still try to track this further.

@lolodomo
Copy link
Contributor

My only remaining comments were about exception handling but I believe you concluded there is in fact no problem. As a consequence, that is fine for me,. Feel free to merge @jlaur

@jaywiseman1971
Copy link

Can someone post the JAR link so I can test this?

I have 2 HUE bridges with over 50 devices across them. I'm running OH 3.2 and the same HUE version binding, my issue is the HUE bridges go offline/online throughout the day very often (just offline for a few milliseconds). Reading this thread, is this because it's using a shared HTTP client? If this is solved, this would be great!

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

Can someone post the JAR link so I can test this?

This version of the binding requires core 3.3 or higher, so you would need to upgrade before being able to test it.

I actually experienced the opposite problem. Shared Jetty client was introduced with this PR and I didn't have timeouts before I began testing this.

@cweitkamp
Copy link
Contributor Author

@jlaur Which other bindings do you use in your environment based on the shared Jetty client?

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

@jlaur Which other bindings do you use in your environment based on the shared Jetty client?

  • miele: Polling interval 15 seconds, each time one call to get devices and one call per device - I have 5. So 18 calls per minute when idle, but they are relatively fast.
  • hdpowerview: Polling interval 1 minute, 4 calls per iteration. Relatively fast. However, every 15 minutes a hard refresh per shade. I have 11, and these calls are quite expensive. Additionally every 12 hours 11 very expensive calls to fresh battery status.
  • boschindego: Polling interval 3 minutes, one call per iteration. Quite cheap.
  • meater: Polling interval 30 seconds, so 2 calls per minute.
  • wemo: One call per minute through HttpUtil.executeUrl, I believe.
  • netatmo
  • harmonyhub
  • unifi: Actually doesn't. Mentioned only because I found this interesting comment:
    // [wip] mgb: disabled due to missing common name attributes with certs
    // this.httpClient = httpClientFactory.getCommonHttpClient();
    httpClient = new HttpClient(new SslContextFactory.Client(true));

@cweitkamp
Copy link
Contributor Author

Interesting. And what about the polling configuration of the hue binding itself? IIRC the binding has three polling jobs. One for lights including groups - frequency is configurable by user in seconds , one for sensors - interval configurable too (in ms, disabled, if 0 or less) and one for scenes - fixed value (10 minutes). Plus one request for each command sent towards Hue Bridge.

@jlaur
Copy link
Contributor

jlaur commented Oct 20, 2022

And what about the polling configuration of the hue binding itself? IIRC the binding has three polling jobs. One for lights including groups - frequency is configurable by user in seconds , one for sensors - interval configurable too (in ms, disabled, if 0 or less) and one for scenes - fixed value (10 minutes). Plus one request for each command sent towards Hue Bridge.

Polling interval is 10 seconds (default). I remember now that I lowered Sensor Polling Interval to 250 ms. I believe that was an attempt to slightly improve responsiveness of some FoH buttons (in lack of SSE).

@andrewfg
Copy link
Contributor

in lack of SSE

=> FYI I am working on SSE for Hue and HDPowerview :)

=> also the Gardena binding uses the shared Jetty client; although it has WebSocket call backs (similar to SSE) so the load is low; but one user has complained that when the WebSocket drops, it breaks other bindings; which may or may not be related ??

https://community.openhab.org/t/gardena-binding-throws-connection-errors-and-seems-to-break-some-bindings/140085

@jlaur jlaur merged commit ee34d92 into openhab:main Oct 22, 2022
@jlaur jlaur added this to the 3.4 milestone Oct 22, 2022
@jlaur
Copy link
Contributor

jlaur commented Oct 22, 2022

@cweitkamp - thanks again!

@cweitkamp cweitkamp deleted the feature-hue-v2-api branch October 23, 2022 07:14
andan67 pushed a commit to andan67/openhab-addons that referenced this pull request Nov 6, 2022
…lient to use jetty shared client (openhab#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
andrasU pushed a commit to andrasU/openhab-addons that referenced this pull request Nov 12, 2022
…lient to use jetty shared client (openhab#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
Signed-off-by: Andras Uhrin <andras.uhrin@gmail.com>
@wborn wborn removed the additional testing preferred The change works for the pull request author. A test from someone else is preferred though. label Dec 23, 2022
borazslo pushed a commit to borazslo/openhab-mideaac-addon that referenced this pull request Jan 8, 2023
…lient to use jetty shared client (openhab#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
psmedley pushed a commit to psmedley/openhab-addons that referenced this pull request Feb 23, 2023
…lient to use jetty shared client (openhab#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
nemerdaud pushed a commit to nemerdaud/openhab-addons that referenced this pull request Feb 28, 2023
…lient to use jetty shared client (openhab#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or new feature for an existing add-on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants