import static org.openhab.binding.helios.internal.HeliosBindingConstants.HELIOS_VARIO_IP_2_21_TYPE;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.client.ClientBuilder;
import org.openhab.binding.helios.internal.handler.HeliosHandler221;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
/**
* The {@link HeliosHandlerFactory} is responsible for creating things and thing
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.helios")
public class HeliosHandlerFactory extends BaseThingHandlerFactory {
+ private static final int EVENT_STREAM_CONNECT_TIMEOUT = 3;
+ private static final int EVENT_STREAM_READ_TIMEOUT = 200;
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(HELIOS_VARIO_IP_2_21_TYPE);
+ private final ClientBuilder clientBuilder;
+
+ @Activate
+ public HeliosHandlerFactory(@Reference ClientBuilder clientBuilder) {
+ this.clientBuilder = clientBuilder //
+ .connectTimeout(EVENT_STREAM_CONNECT_TIMEOUT, TimeUnit.SECONDS)
+ .readTimeout(EVENT_STREAM_READ_TIMEOUT, TimeUnit.SECONDS);
+ }
+
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(HELIOS_VARIO_IP_2_21_TYPE)) {
- return new HeliosHandler221(thing);
+ return new HeliosHandler221(thing, clientBuilder);
}
return null;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
// REST Client API variables
private Client heliosClient;
+ private final ClientBuilder heliosClientBuilder;
private WebTarget baseTarget;
private WebTarget systemTarget;
private WebTarget logTarget;
private long logSubscriptionID = 0;
- public HeliosHandler221(Thing thing) {
+ public HeliosHandler221(Thing thing, ClientBuilder heliosClientBuilder) {
super(thing);
+ this.heliosClientBuilder = heliosClientBuilder;
}
@Override
logger.error("An exception occurred while initialising the SSL context : '{}'", e1.getMessage(), e1);
}
- heliosClient = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(new HostnameVerifier() {
+ heliosClient = heliosClientBuilder.sslContext(sslContext).hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return true;
}).build();
heliosClient.register(new Authenticator(username, password));
- baseTarget = heliosClient.target(BASE_URI);
+ baseTarget = heliosClient.target(BASE_URI.replace("{ip}", ipAddress));
systemTarget = baseTarget.path(SYSTEM_PATH);
logTarget = baseTarget.path(LOG_PATH);
switchTarget = baseTarget.path(SWITCH_PATH);
Response response = null;
try {
- response = systemTarget.resolveTemplate("ip", ipAddress).resolveTemplate("cmd", INFO)
- .request(MediaType.APPLICATION_JSON_TYPE).get();
- } catch (NullPointerException e) {
+ response = systemTarget.resolveTemplate("cmd", INFO).request(MediaType.APPLICATION_JSON_TYPE).get();
+ } catch (ProcessingException e) {
logger.debug("An exception occurred while fetching system info of the Helios IP Vario '{}' : '{}'",
getThing().getUID().toString(), e.getMessage(), e);
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
scheduler.schedule(resetRunnable, RESET_INTERVAL, TimeUnit.SECONDS);
return;
}
@Override
public void dispose() {
logger.debug("Disposing the Helios IP Vario handler for '{}'.", getThing().getUID().toString());
+ tearDown();
+ }
+
+ private void tearDown() {
+ logger.debug("Tearing down the Helios IP Vario handler for '{}'.", getThing().getUID().toString());
if (logSubscriptionID != 0) {
unsubscribe();
protected Runnable resetRunnable = () -> {
logger.debug("Resetting the Helios IP Vario handler for '{}'", getThing().getUID());
- dispose();
+ tearDown();
initialize();
};
ThingBuilder thingBuilder = editThing();
ChannelTypeUID enablerUID = new ChannelTypeUID(BINDING_ID, SWITCH_ENABLER);
ChannelTypeUID triggerUID = new ChannelTypeUID(BINDING_ID, SWITCH_TRIGGER);
-
- Channel channel = ChannelBuilder
- .create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id + "active"), "Switch")
- .withType(enablerUID).build();
- thingBuilder.withChannel(channel);
- channel = ChannelBuilder
- .create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id), "Switch")
- .withType(triggerUID).build();
- thingBuilder.withChannel(channel);
+ ChannelUID activeSwitchChannelUID = new ChannelUID(getThing().getUID(),
+ "switch" + aSwitch.id + "active");
+ ChannelUID switchChannelUID = new ChannelUID(getThing().getUID(), "switch" + aSwitch.id);
+
+ if (this.getThing().getChannel(activeSwitchChannelUID) == null) {
+ logger.trace(
+ "Adding a channel with id '{}' to the Helios IP Vario '{}' for the switch with id '{}'",
+ activeSwitchChannelUID, getThing().getUID().toString(), aSwitch.id);
+ Channel channel = ChannelBuilder.create(activeSwitchChannelUID, "Switch").withType(enablerUID)
+ .build();
+ thingBuilder.withChannel(channel);
+ }
+ if (this.getThing().getChannel(switchChannelUID) == null) {
+ logger.trace(
+ "Adding a channel with id '{}' to the Helios IP Vario '{}' for the switch with id '{}'",
+ switchChannelUID, getThing().getUID().toString(), aSwitch.id);
+ Channel channel = ChannelBuilder.create(switchChannelUID, "Switch").withType(triggerUID)
+ .build();
+ thingBuilder.withChannel(channel);
+ }
updateThing(thingBuilder.build());
}
}
getThing().getUID().toString(), aPort.port);
ThingBuilder thingBuilder = editThing();
ChannelTypeUID triggerUID = new ChannelTypeUID(BINDING_ID, IO_TRIGGER);
+ ChannelUID ioChannelUID = new ChannelUID(getThing().getUID(), "io" + aPort.port);
Map<String, String> channelProperties = new HashMap<>();
channelProperties.put("type", aPort.type);
- Channel channel = ChannelBuilder
- .create(new ChannelUID(getThing().getUID(), "io" + aPort.port), "Switch").withType(triggerUID)
- .withProperties(channelProperties).build();
- thingBuilder.withChannel(channel);
+ if (this.getThing().getChannel(ioChannelUID) == null) {
+ logger.trace(
+ "Adding a channel with id '{}' to the Helios IP Vario '{}' for the switch with id '{}'",
+ ioChannelUID.getId(), getThing().getUID().toString(), aPort.port);
+ Channel channel = ChannelBuilder.create(ioChannelUID, "Switch").withType(triggerUID)
+ .withProperties(channelProperties).build();
+ thingBuilder.withChannel(channel);
+ }
updateThing(thingBuilder.build());
}
}
logger.trace("No events were retrieved");
}
}
+ } catch (ProcessingException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+ logger.trace("An underlying exception forced the Helios IP Vario to go offline : '{}'",
+ e.getMessage(), e);
+ scheduler.schedule(resetRunnable, RESET_INTERVAL, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("An exception occurred while processing an event : '{}'", e.getMessage(), e);
}