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

[boschshc] Release v1.1 #10097

Merged
merged 13 commits into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 10 additions & 6 deletions bundles/org.openhab.binding.boschshc/DEVELOPERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Build

To only build the Bosch SHC binding code execute
To only build the Bosch Smart Home binding code execute

mvn -pl :org.openhab.binding.boschshc install

Expand All @@ -15,28 +15,32 @@ For the first time the jar is loaded automatically as a bundle.

It should also be reloaded automatically when the jar changed.

To reload the bundle manually you need to execute:
To reload the bundle manually you need to execute in the openhab console:

bundle:update "openHAB Add-ons :: Bundles :: BoschSHC Binding"
bundle:update "openHAB Add-ons :: Bundles :: Bosch Smart Home Binding"

or get the ID and update the bundle using the ID:

bundle:list
-> Get ID for "openHAB Add-ons :: Bundles :: BoschSHC Binding"
-> Get ID for "openHAB Add-ons :: Bundles :: Bosch Smart Home Binding"
bundle:update <ID>


## Debugging

To get debug output and traces of the Bosch SHC binding code
To get debug output and traces of the Bosch Smart Home binding code
add the following lines into ``userdata/etc/log4j2.xml`` Loggers XML section.

<!-- Bosch SHC for debugging -->
<Logger level="TRACE" name="org.openhab.binding.boschshc"/>

or use the openhab console to change the log level

log:set TRACE org.openhab.binding.boschshc

## Pairing and Certificates

We need secured and paired connection from the openHAB binding instance to the Bosch SHC.
We need secured and paired connection from the openHAB binding instance to the Bosch Smart Home Controller (SHC).

Read more about the pairing process in [register a new client to the bosch smart home controller](https://github.com/BoschSmartHome/bosch-shc-api-docs/tree/master/postman#register-a-new-client-to-the-bosch-smart-home-controller)

Expand Down
12 changes: 6 additions & 6 deletions bundles/org.openhab.binding.boschshc/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# BoschSHC Binding
# Bosch Smart Home Binding

Binding for the Bosch Smart Home Controller.
Binding for the Bosch Smart Home.

- [BoschSHC Binding](#boschshc-binding)
- [Bosch Smart Home Binding](#bosch-smart-home-binding)
- [Supported Things](#supported-things)
- [Bosch In-Wall switches & Bosch Smart Plugs](#bosch-in-wall-switches--bosch-smart-plugs)
- [Bosch TwinGuard smoke detector](#bosch-twinguard-smoke-detector)
Expand All @@ -13,7 +13,7 @@ Binding for the Bosch Smart Home Controller.
- [Bosch Climate Control](#bosch-climate-control)
- [Limitations](#limitations)
- [Discovery](#discovery)
- [Binding Configuration](#binding-configuration)
- [Bridge Configuration](#bridge-configuration)
- [Getting the device IDs](#getting-the-device-ids)
- [Thing Configuration](#thing-configuration)
- [Item Configuration](#item-configuration)
Expand Down Expand Up @@ -102,8 +102,8 @@ You need to provide the IP address and the system password of your Bosch Smart H
The IP address of the controller is visible in the Bosch Smart Home Mobile App (More -> System -> Smart Home Controller) or in your network router UI.
The system password is set by you during your initial registration steps in the _Bosch Smart Home App_.

A keystore file with a self signed certificate is created automatically.
This certificate is used for pairing between the Bridge and the Bosch SHC.
A keystore file with a self-signed certificate is created automatically.
This certificate is used for pairing between the Bridge and the Bosch Smart Home Controller.

*Press and hold the Bosch Smart Home Controller Bridge button until the LED starts blinking after you save your settings for pairing*.

Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.boschshc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<artifactId>org.openhab.binding.boschshc</artifactId>

<name>openHAB Add-ons :: Bundles :: BoschSHC Binding</name>
<name>openHAB Add-ons :: Bundles :: Bosch Smart Home Binding</name>

<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<features name="org.openhab.binding.boschshc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-boschshc" description="BoschSHC Binding" version="${project.version}">
<feature name="openhab-binding-boschshc" description="Bosch Smart Home Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.boschshc/${project.version}</bundle>
</feature>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -60,6 +61,16 @@ public BoschHttpClient(String ipAddress, String systemPassword, SslContextFactor
this.systemPassword = systemPassword;
}

/**
* Returns the public information URL for the Bosch SHC clients, using port 8446.
* See https://github.com/BoschSmartHome/bosch-shc-api-docs/blob/master/postman/README.md
*
* @return URL for public information
*/
public String getPublicInformationUrl() {
return String.format("https://%s:8446/smarthome/public/information", this.ipAddress);
}

/**
* Returns the pairing URL for the Bosch SHC clients, using port 8443.
* See https://github.com/BoschSmartHome/bosch-shc-api-docs/blob/master/postman/README.md
Expand Down Expand Up @@ -102,22 +113,60 @@ public String getServiceUrl(String serviceName, String deviceId) {
return this.getBoschSmartHomeUrl(String.format("devices/%s/services/%s/state", deviceId, serviceName));
}

/**
* Checks if the Bosch SHC is online.
*
* The HTTP server could be offline (Timeout of request).
* Or during boot-up the server can response e.g. with SERVICE_UNAVAILABLE_503
*
* Will return true, if the server responds with the "public information".
*
*
* @return true if HTTP server is online
* @throws InterruptedException in case of an interrupt
*/
public boolean isOnline() throws InterruptedException {
try {
String url = this.getPublicInformationUrl();
Request request = this.createRequest(url, GET);
ContentResponse contentResponse = request.send();
if (HttpStatus.getCode(contentResponse.getStatus()).isSuccess()) {
String content = contentResponse.getContentAsString();
logger.debug("Online check completed with success: {} - status code: {}", content,
contentResponse.getStatus());
return true;
} else {
logger.debug("Online check failed with status code: {}", contentResponse.getStatus());
return false;
}
} catch (TimeoutException | ExecutionException | NullPointerException e) {
logger.debug("Online check failed because of {}!", e.getMessage());
return false;
}
}

/**
* Checks if the Bosch SHC can be accessed.
*
* @return true if HTTP access was successful
*
* @return true if HTTP access to SHC devices was successful
* @throws InterruptedException in case of an interrupt
*/
public boolean isAccessPossible() throws InterruptedException {
try {
String url = this.getBoschSmartHomeUrl("devices");
Request request = this.createRequest(url, GET);
ContentResponse contentResponse = request.send();
String content = contentResponse.getContentAsString();
logger.debug("Access check response complete: {} - return code: {}", content, contentResponse.getStatus());
return true;
if (HttpStatus.getCode(contentResponse.getStatus()).isSuccess()) {
String content = contentResponse.getContentAsString();
logger.debug("Access check completed with success: {} - status code: {}", content,
contentResponse.getStatus());
return true;
} else {
logger.debug("Access check failed with status code: {}", contentResponse.getStatus());
return false;
}
} catch (TimeoutException | ExecutionException | NullPointerException e) {
logger.debug("Access check response failed because of {}!", e.getMessage());
logger.debug("Access check failed because of {}!", e.getMessage());
return false;
}
}
Expand All @@ -130,8 +179,8 @@ public boolean isAccessPossible() throws InterruptedException {
* @throws InterruptedException in case of an interrupt
*/
public boolean doPairing() throws InterruptedException {
logger.trace("Starting pairing openHAB Client with Bosch SmartHomeController!");
logger.trace("Please press the Bosch SHC button until LED starts blinking");
logger.trace("Starting pairing openHAB Client with Bosch Smart Home Controller!");
logger.trace("Please press the Bosch Smart Home Controller button until LED starts blinking");

ContentResponse contentResponse;
try {
Expand Down Expand Up @@ -169,7 +218,7 @@ public boolean doPairing() throws InterruptedException {
// javax.net.ssl.SSLHandshakeException: General SSLEngine problem
// => usually the pairing failed, because hardware button was not pressed.
logger.trace("Pairing failed - Details: {}", e.getMessage());
logger.warn("Pairing failed. Was the Bosch SHC button pressed?");
logger.warn("Pairing failed. Was the Bosch Smart Home Controller button pressed?");
return false;
}
}
Expand All @@ -194,7 +243,12 @@ public Request createRequest(String url, HttpMethod method) {
* @return created HTTP request instance
*/
public Request createRequest(String url, HttpMethod method, @Nullable Object content) {
Request request = this.newRequest(url).method(method).header("Content-Type", "application/json");
logger.trace("Create request for http client {}", this.toString());

Request request = this.newRequest(url).method(method).header("Content-Type", "application/json")
.header("api-version", "2.1") // see https://github.com/BoschSmartHome/bosch-shc-api-docs/issues/46
coeing marked this conversation as resolved.
Show resolved Hide resolved
.timeout(10, TimeUnit.SECONDS); // Set default timeout

if (content != null) {
String body = GSON.toJson(content);
logger.trace("create request for {} and content {}", url, body);
Expand All @@ -203,9 +257,6 @@ public Request createRequest(String url, HttpMethod method, @Nullable Object con
logger.trace("create request for {}", url);
}

// Set default timeout
request.timeout(10, TimeUnit.SECONDS);

return request;
}

Expand All @@ -220,9 +271,11 @@ public Request createRequest(String url, HttpMethod method, @Nullable Object con
*/
public <TContent> TContent sendRequest(Request request, Class<TContent> responseContentClass)
throws InterruptedException, TimeoutException, ExecutionException {
logger.trace("Send request: {}", request.toString());

ContentResponse contentResponse = request.send();

logger.debug("BoschHttpClient: response complete: {} - return code: {}", contentResponse.getContentAsString(),
logger.debug("Received response: {} - status: {}", contentResponse.getContentAsString(),
contentResponse.getStatus());

try {
Expand Down