Skip to content

Commit

Permalink
🔓 Registration (acquire API token)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Gfeller <[email protected]>
  • Loading branch information
pgfeller committed Mar 12, 2024
1 parent 54103c6 commit 32a3d88
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2024-2024 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.huesync.internal.api.dto.registration;

/**
*
* @author Patrik Gfeller - Initial Contribution
*/
public class HueSyncRegistration {
public String registrationId;
public String accessToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
@NonNullByDefault
public class HueSyncConfiguration {
public String registrationId = "";
public String apiAccessToken = "";
public String host = "";
public Integer port = 443;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
import java.util.concurrent.TimeoutException;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
import org.openhab.binding.huesync.internal.HueSyncConstants;
import org.openhab.binding.huesync.internal.api.dto.HueSyncDeviceInfo;
import org.openhab.binding.huesync.internal.api.dto.registration.HueSyncRegistration;
import org.openhab.binding.huesync.internal.api.dto.registration.HueSyncRegistrationRequest;
import org.openhab.binding.huesync.internal.config.HueSyncConfiguration;
import org.slf4j.Logger;
Expand Down Expand Up @@ -80,7 +83,17 @@ public HueSyncDeviceInfo getDeviceInfo() throws InterruptedException, ExecutionE
return this.deviceInfo;
}

public void registerDevice()
/**
* Try to register the application with the device.
*
* @return null || HueSyncRegistration
*
* @throws JsonProcessingException
* @throws InterruptedException
* @throws TimeoutException
* @throws ExecutionException
*/
public @Nullable HueSyncRegistration registerDevice()
throws JsonProcessingException, InterruptedException, TimeoutException, ExecutionException {

HueSyncRegistrationRequest dto = new HueSyncRegistrationRequest();
Expand All @@ -95,6 +108,8 @@ public void registerDevice()
.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.APPLICATION_JSON.asString())
.content(new StringContentProvider(json)).timeout(500, TimeUnit.MILLISECONDS).send();

logger.trace("registerDevice", response);
return (response.getStatus() == HttpStatus.OK_200)
? ObjectMapper.readValue(response.getContentAsString(), HueSyncRegistration.class)
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.huesync.internal.HueSyncConstants;
import org.openhab.binding.huesync.internal.api.dto.HueSyncDeviceInfo;
import org.openhab.binding.huesync.internal.api.dto.registration.HueSyncRegistration;
import org.openhab.binding.huesync.internal.config.HueSyncConfiguration;
import org.openhab.binding.huesync.internal.connection.HueSyncConnection;
import org.openhab.binding.huesync.internal.connection.HueSyncTrustManagerProvider;
import org.openhab.binding.huesync.internal.exceptions.HueSyncApiException;
import org.openhab.binding.huesync.internal.util.HueSyncLogLocalizer;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.io.net.http.TlsTrustManagerProvider;
import org.openhab.core.thing.ChannelUID;
Expand All @@ -50,6 +52,9 @@
*/
@NonNullByDefault
public class HueSyncHandler extends BaseThingHandler {
/** the device registration id */
static final String REGISTRATION_ID = "registrationId";
static final String API_TOKEN = "apiAccessToken";

/** the key for the api version property */
static final String PROPERTY_API_VERSION = "apiVersion";
Expand All @@ -62,7 +67,7 @@ public class HueSyncHandler extends BaseThingHandler {
private HueSyncConfiguration config;

private @Nullable BundleContext context;
private @Nullable ScheduledFuture<?> registrationJob;
private @Nullable ScheduledFuture<?> registrationTask;

private @Nullable HueSyncConnection connection;
private @Nullable HueSyncDeviceInfo deviceInfo;
Expand Down Expand Up @@ -103,7 +108,7 @@ public void initialize() {

this.deviceInfo = this.connection.getDeviceInfo();

Map<String, String> properties = editProperties();
Map<String, String> properties = this.editProperties();

properties.put(Thing.PROPERTY_SERIAL_NUMBER, this.deviceInfo.uniqueId);
properties.put(Thing.PROPERTY_MODEL_ID, this.deviceInfo.deviceType);
Expand Down Expand Up @@ -140,9 +145,33 @@ private void startRegistrationJob() {
this.logger.info("Starting registration job for {} {}:{}", this.deviceInfo.name, this.deviceInfo.deviceType,
this.deviceInfo.uniqueId);

this.registrationJob = scheduler.scheduleWithFixedDelay(() -> {
this.registrationTask = scheduler.scheduleWithFixedDelay(() -> {
try {
this.connection.registerDevice();
if (this.thing.getStatus() == ThingStatus.OFFLINE) {
HueSyncRegistration registration = this.connection.registerDevice();

if (registration != null) {
Map<String, String> properties = this.editProperties();

properties.put(HueSyncHandler.PROPERTY_API_VERSION,
String.format("%d", this.deviceInfo.apiLevel));
properties.put(HueSyncHandler.REGISTRATION_ID, registration.registrationId);

this.config.registrationId = registration.registrationId;
this.config.apiAccessToken = registration.accessToken;

Configuration configuration = this.editConfiguration();

configuration.put(HueSyncHandler.REGISTRATION_ID, this.config.registrationId);
configuration.put(HueSyncHandler.API_TOKEN, this.config.apiAccessToken);

this.updateConfiguration(configuration);
this.updateProperties(properties);
this.updateStatus(ThingStatus.ONLINE);

this.registrationTask.cancel(false);
}
}
} catch (Exception e) {
// TODO: ...
}
Expand All @@ -151,10 +180,10 @@ private void startRegistrationJob() {

private void checkRegistration() {
if (this.config.apiAccessToken.isEmpty() || this.config.apiAccessToken.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
"@text/thing.config.huesync.box.registration");
} else {
updateStatus(ThingStatus.ONLINE);
this.updateStatus(ThingStatus.ONLINE);
}
}

Expand All @@ -170,9 +199,9 @@ public void dispose() {
super.dispose();

try {
if (this.registrationJob != null && !this.registrationJob.isDone()) {
this.registrationJob.cancel(true);
this.registrationJob = null;
if (this.registrationTask != null && !this.registrationTask.isDone()) {
this.registrationTask.cancel(true);
this.registrationTask = null;
}

if (this.serviceRegistration != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ thing-type.config.huesync.box.host.label = Network Address
thing-type.config.huesync.box.host.description = Network address of the HDMI Sync Box.
thing-type.config.huesync.box.port.label = Port
thing-type.config.huesync.box.port.description = Port of the HDMI Sync Box.
thing-type.config.huesync.box.registrationId.label = Application Registration Id
thing-type.config.huesync.box.registrationId.description = The id of the API registration.

# api exceptions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
<default>443</default>
<required>true</required>
</parameter>

<parameter name="registrationId" type="text" groupName="connection">
<context></context>
<label>Application Registration Id</label>
<description>The id of the API registration.</description>
<required>false</required>
</parameter>
<parameter name="apiAccessToken" type="text" groupName="connection">
<context>password</context>
<label>API Access Token</label>
Expand All @@ -42,6 +49,7 @@
seconds to grant the binding the required permissions.</description>
<required>false</required>
</parameter>

</config-description>

</thing-type>
Expand Down

0 comments on commit 32a3d88

Please sign in to comment.