import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
private @NonNullByDefault({}) Ipx800Configuration configuration;
private @NonNullByDefault({}) Ipx800DeviceConnector connector;
- private @Nullable M2MMessageParser parser;
private @NonNullByDefault({}) StatusFileInterpreter statusFile;
- private @Nullable ScheduledFuture<?> refreshJob;
- private final Map<String, PortData> portDatas = new HashMap<>();
+ private Optional<M2MMessageParser> parser = Optional.empty();
+ private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
+
+ private final Map<String, @Nullable PortData> portDatas = new HashMap<>();
private class LongPressEvaluator implements Runnable {
private final ZonedDateTime referenceTime;
}
@Override
- @SuppressWarnings("PMD.CompareObjectsWithEquals")
public void run() {
PortData currentData = portDatas.get(port);
- if (currentData != null && currentData.getValue() == 1 && currentData.getTimestamp() == referenceTime) {
+ if (currentData != null && currentData.getValue() == 1
+ && referenceTime.equals(currentData.getTimestamp())) {
triggerChannel(eventChannelId, EVENT_LONG_PRESS);
}
}
@Override
public void initialize() {
-
configuration = getConfigAs(Ipx800Configuration.class);
logger.debug("Initializing IPX800 handler for uid '{}'", getThing().getUID());
discoverAttributes();
}
+ List<Channel> channels = new ArrayList<>(getThing().getChannels());
+ ThingBuilder thingBuilder = editThing();
+ PortDefinition.asStream().forEach(portDefinition -> {
+ int nbElements = statusFile.getMaxNumberofNodeType(portDefinition);
+ for (int i = 0; i < nbElements; i++) {
+ createChannels(portDefinition, i, channels);
+ }
+ });
+ thingBuilder.withChannels(channels);
+ updateThing(thingBuilder.build());
+
connector = new Ipx800DeviceConnector(configuration.hostname, configuration.portNumber, getThing().getUID());
- parser = new M2MMessageParser(connector, this);
+ parser = Optional.of(new M2MMessageParser(connector, this));
updateStatus(ThingStatus.UNKNOWN);
- refreshJob = scheduler.scheduleWithFixedDelay(statusFile::read, 3000, configuration.pullInterval,
- TimeUnit.MILLISECONDS);
+ refreshJob = Optional.of(scheduler.scheduleWithFixedDelay(statusFile::read, 3000, configuration.pullInterval,
+ TimeUnit.MILLISECONDS));
connector.start();
}
@Override
public void dispose() {
- if (refreshJob != null) {
- refreshJob.cancel(true);
- refreshJob = null;
- }
+ refreshJob.ifPresent(job -> job.cancel(true));
+ refreshJob = Optional.empty();
if (connector != null) {
connector.destroyAndExit();
}
- parser = null;
+ parser = Optional.empty();
portDatas.values().stream().forEach(portData -> {
- portData.destroy();
+ if (portData != null) {
+ portData.dispose();
+ }
});
super.dispose();
}
protected void discoverAttributes() {
- final Map<String, String> properties = new HashMap<>();
-
- properties.put(Thing.PROPERTY_VENDOR, "GCE Electronics");
- properties.put(Thing.PROPERTY_FIRMWARE_VERSION, statusFile.getElement(StatusEntry.VERSION));
- properties.put(Thing.PROPERTY_MAC_ADDRESS, statusFile.getElement(StatusEntry.CONFIG_MAC));
- updateProperties(properties);
-
- ThingBuilder thingBuilder = editThing();
- List<Channel> channels = new ArrayList<>(getThing().getChannels());
-
- PortDefinition.asStream().forEach(portDefinition -> {
- int nbElements = statusFile.getMaxNumberofNodeType(portDefinition);
- for (int i = 0; i < nbElements; i++) {
- createChannels(portDefinition, i, channels);
- }
- });
+ updateProperties(Map.of(Thing.PROPERTY_VENDOR, "GCE Electronics", Thing.PROPERTY_FIRMWARE_VERSION,
+ statusFile.getElement(StatusEntry.VERSION), Thing.PROPERTY_MAC_ADDRESS,
+ statusFile.getElement(StatusEntry.CONFIG_MAC)));
+ }
- thingBuilder.withChannels(channels);
- updateThing(thingBuilder.build());
+ private void addIfChannelAbsent(ChannelBuilder channelBuilder, List<Channel> channels) {
+ Channel newChannel = channelBuilder.build();
+ if (channels.stream().noneMatch(c -> c.getUID().equals(newChannel.getUID()))) {
+ channels.add(newChannel);
+ }
}
private void createChannels(PortDefinition portDefinition, int portIndex, List<Channel> channels) {
ChannelTypeUID channelType = new ChannelTypeUID(BINDING_ID, advancedChannelTypeName);
switch (portDefinition) {
case ANALOG:
- channels.add(ChannelBuilder.create(mainChannelUID, CoreItemFactory.NUMBER)
- .withLabel("Analog Input " + ndx).withType(channelType).build());
- channels.add(ChannelBuilder
- .create(new ChannelUID(groupUID, ndx + "-voltage"), "Number:ElectricPotential")
- .withLabel("Voltage " + ndx).withType(new ChannelTypeUID(BINDING_ID, CHANNEL_VOLTAGE)).build());
+ addIfChannelAbsent(ChannelBuilder.create(mainChannelUID, CoreItemFactory.NUMBER)
+ .withLabel("Analog Input " + ndx).withType(channelType), channels);
+ addIfChannelAbsent(
+ ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-voltage"), "Number:ElectricPotential")
+ .withType(new ChannelTypeUID(BINDING_ID, CHANNEL_VOLTAGE)).withLabel("Voltage " + ndx),
+ channels);
break;
case CONTACT:
- channels.add(ChannelBuilder.create(mainChannelUID, CoreItemFactory.CONTACT).withLabel("Contact " + ndx)
- .withType(channelType).build());
- channels.add(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-event"), null)
- .withLabel("Contact " + ndx + " Event").withKind(ChannelKind.TRIGGER)
+ addIfChannelAbsent(ChannelBuilder.create(mainChannelUID, CoreItemFactory.CONTACT)
+ .withLabel("Contact " + ndx).withType(channelType), channels);
+ addIfChannelAbsent(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-event"), null)
.withType(new ChannelTypeUID(BINDING_ID, TRIGGER_CONTACT + (portIndex < 8 ? "" : "Advanced")))
- .build());
+ .withLabel("Contact " + ndx + " Event").withKind(ChannelKind.TRIGGER), channels);
break;
case COUNTER:
- channels.add(ChannelBuilder.create(mainChannelUID, CoreItemFactory.NUMBER).withLabel("Counter " + ndx)
- .withType(channelType).build());
+ addIfChannelAbsent(ChannelBuilder.create(mainChannelUID, CoreItemFactory.NUMBER)
+ .withLabel("Counter " + ndx).withType(channelType), channels);
break;
case RELAY:
- channels.add(ChannelBuilder.create(mainChannelUID, CoreItemFactory.SWITCH).withLabel("Relay " + ndx)
- .withType(channelType).build());
+ addIfChannelAbsent(ChannelBuilder.create(mainChannelUID, CoreItemFactory.SWITCH)
+ .withLabel("Relay " + ndx).withType(channelType), channels);
break;
}
- channels.add(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-duration"), "Number:Time")
- .withLabel("Previous state duration " + ndx)
- .withType(new ChannelTypeUID(BINDING_ID, CHANNEL_LAST_STATE_DURATION)).build());
+ addIfChannelAbsent(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-duration"), "Number:Time")
+ .withType(new ChannelTypeUID(BINDING_ID, CHANNEL_LAST_STATE_DURATION))
+ .withLabel("Previous state duration " + ndx), channels);
}
@Override
if (portDefinition == PortDefinition.ANALOG) { // For analog values, check histeresis
AnalogInputConfiguration config = configuration.as(AnalogInputConfiguration.class);
long hysteresis = config.hysteresis / 2;
- if (newValue <= prevValue + hysteresis && newValue >= prevValue - hysteresis) {
- return true;
- }
- }
- if (portDefinition == PortDefinition.CONTACT) { // For contact values, check debounce
+ return (newValue <= prevValue + hysteresis && newValue >= prevValue - hysteresis);
+ } else if (portDefinition == PortDefinition.CONTACT) { // For contact values, check debounce
DigitalInputConfiguration config = configuration.as(DigitalInputConfiguration.class);
- if (config.debouncePeriod != 0
- && now.isBefore(portData.getTimestamp().plus(config.debouncePeriod, ChronoUnit.MILLIS))) {
- return true;
- }
+ return (config.debouncePeriod != 0
+ && now.isBefore(portData.getTimestamp().plus(config.debouncePeriod, ChronoUnit.MILLIS)));
}
}
return false;
&& PortDefinition.fromGroupId(groupId) == PortDefinition.RELAY) {
RelayOutputConfiguration config = channel.getConfiguration().as(RelayOutputConfiguration.class);
String id = channelUID.getIdWithoutGroup();
- if (parser != null) {
- parser.setOutput(id, (OnOffType) command == OnOffType.ON ? 1 : 0, config.pulse);
- }
+ parser.ifPresent(p -> p.setOutput(id, (OnOffType) command == OnOffType.ON ? 1 : 0, config.pulse));
return;
}
logger.debug("Can not handle command '{}' on channel '{}'", command, channelUID);
super.channelUnlinked(channelUID);
PortData portData = portDatas.remove(channelUID.getId());
if (portData != null) {
- portData.destroy();
+ portData.dispose();
}
}
public void resetCounter(int counter) {
- if (parser != null) {
- parser.resetCounter(counter);
- }
+ parser.ifPresent(p -> p.resetCounter(counter));
}
public void reset() {
- if (parser != null) {
- parser.resetPLC();
- }
+ parser.ifPresent(M2MMessageParser::resetPLC);
}
@Override