From c75ea37b3c55dba70b7de750769f929d2bfe295c Mon Sep 17 00:00:00 2001 From: Konstantin Polihronov Date: Tue, 23 Jul 2019 11:46:55 +0300 Subject: [PATCH] [paradoxalarm] - Discovery service implementation (#5826) * Discovery service implementation Signed-off-by: Konstantin Polihronov Signed-off-by: Maximilian Hess --- .../discovery/ParadoxDiscoveryService.java | 115 ++++++++++++++++++ .../ParadoxAlarmBindingConstants.java | 21 +++- .../handlers/ParadoxAlarmHandlerFactory.java | 36 +++++- .../handlers/ParadoxIP150BridgeHandler.java | 7 +- .../paradoxalarm/internal/model/Entity.java | 2 +- 5 files changed, 167 insertions(+), 14 deletions(-) create mode 100644 bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java new file mode 100644 index 0000000000000..546df5bb6a2cf --- /dev/null +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2010-2019 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.paradoxalarm.internal.discovery; + +import static org.openhab.binding.paradoxalarm.internal.handlers.ParadoxAlarmBindingConstants.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; +import org.eclipse.smarthome.config.discovery.DiscoveryResult; +import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.openhab.binding.paradoxalarm.internal.communication.IParadoxCommunicator; +import org.openhab.binding.paradoxalarm.internal.exceptions.ParadoxRuntimeException; +import org.openhab.binding.paradoxalarm.internal.handlers.ParadoxIP150BridgeHandler; +import org.openhab.binding.paradoxalarm.internal.model.ParadoxInformation; +import org.openhab.binding.paradoxalarm.internal.model.ParadoxPanel; +import org.openhab.binding.paradoxalarm.internal.model.Partition; +import org.openhab.binding.paradoxalarm.internal.model.Zone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ParadoxDiscoveryService} is responsible for discovery of partitions, zones and the panel once bridge is + * created. + * + * @author Konstnatin Polihronov - Initial Contribution + */ +public class ParadoxDiscoveryService extends AbstractDiscoveryService { + + private final Logger logger = LoggerFactory.getLogger(ParadoxDiscoveryService.class); + + private ParadoxIP150BridgeHandler ip150BridgeHandler; + + public ParadoxDiscoveryService(ParadoxIP150BridgeHandler ip150BridgeHandler) { + super(SUPPORTED_THING_TYPES_UIDS, 15, false); + this.ip150BridgeHandler = ip150BridgeHandler; + } + + @Override + protected void startScan() { + IParadoxCommunicator communicator = ip150BridgeHandler.getCommunicator(); + if (communicator != null && communicator.isOnline()) { + ParadoxPanel panel = ParadoxPanel.getInstance(); + discoverPanel(panel.getPanelInformation()); + discoverPartitions(panel.getPartitions()); + discoverZones(panel.getZones()); + } else { + logger.debug("Communicator null or not online. Trace={}", new ParadoxRuntimeException()); + } + } + + private void discoverPanel(ParadoxInformation panelInformation) { + if (panelInformation != null) { + Map properties = new HashMap<>(); + properties.put(PANEL_TYPE_PROPERTY_NAME, panelInformation.getPanelType().name()); + properties.put(PANEL_SERIAL_NUMBER_PROPERTY_NAME, panelInformation.getSerialNumber()); + properties.put(PANEL_APPLICATION_VERSION_PROPERTY_NAME, panelInformation.getApplicationVersion()); + properties.put(PANEL_BOOTLOADER_VERSION_PROPERTY_NAME, panelInformation.getBootLoaderVersion()); + properties.put(PANEL_HARDWARE_VERSION_PROPERTY_NAME, panelInformation.getHardwareVersion()); + + ThingUID bridgeUid = ip150BridgeHandler.getThing().getUID(); + ThingUID thingUID = new ThingUID(PANEL_THING_TYPE_UID, bridgeUid, PARADOX_PANEL_THING_TYPE_ID); + DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withProperties(properties) + .withBridge(bridgeUid).withLabel("Paradox panel - " + panelInformation.getPanelType()).build(); + logger.debug("Panel DiscoveryResult={}", result); + thingDiscovered(result); + } + } + + private void discoverPartitions(List partitions) { + partitions.stream().forEach(partition -> { + String thingId = PARTITION_THING_TYPE_ID + partition.getId(); + String label = partition.getLabel(); + ThingUID bridgeUid = ip150BridgeHandler.getThing().getUID(); + + ThingUID thingUID = new ThingUID(PARTITION_THING_TYPE_UID, bridgeUid, thingId); + DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUid) + .withLabel("Partition " + label).withProperty(PARTITION_THING_TYPE_ID, thingId) + .withProperty("id", partition.getId()).build(); + logger.debug("Partition DiscoveryResult={}", result); + + thingDiscovered(result); + }); + } + + private void discoverZones(List zones) { + zones.stream().forEach(zone -> { + String thingId = zone.getLabel().replaceAll(" ", "_"); + String label = zone.getLabel(); + ThingUID bridgeUid = ip150BridgeHandler.getThing().getUID(); + + ThingUID thingUID = new ThingUID(ZONE_THING_TYPE_UID, bridgeUid, thingId); + DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUid) + .withLabel("Zone " + label).withProperty(ZONE_THING_TYPE_ID, thingId) + .withProperty("id", zone.getId()).build(); + logger.debug("Zone DiscoveryResult={}", result); + + thingDiscovered(result); + }); + } + +} diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmBindingConstants.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmBindingConstants.java index 2b72715c26c80..e4b36d4ea85cd 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmBindingConstants.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmBindingConstants.java @@ -12,6 +12,11 @@ */ package org.openhab.binding.paradoxalarm.internal.handlers; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.ThingTypeUID; @@ -25,23 +30,27 @@ @NonNullByDefault public class ParadoxAlarmBindingConstants { - private static final String BINDING_ID = "paradoxalarm"; + public static final String BINDING_ID = "paradoxalarm"; - private static final String PARADOX_COMMUNICATOR_THING_TYPE_ID = "ip150"; + public static final String PARADOX_COMMUNICATOR_THING_TYPE_ID = "ip150"; - private static final String PARADOX_PANEL_THING_TYPE_ID = "panel"; + public static final String PARADOX_PANEL_THING_TYPE_ID = "panel"; - private static final String PARTITION_THING_TYPE_ID = "partition"; + public static final String PARTITION_THING_TYPE_ID = "partition"; - private static final String ZONE_THING_TYPE_ID = "zone"; + public static final String ZONE_THING_TYPE_ID = "zone"; // List of all Thing Type UIDs public static final ThingTypeUID COMMUNICATOR_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, - PARADOX_COMMUNICATOR_THING_TYPE_ID); + PARADOX_COMMUNICATOR_THING_TYPE_ID); public static final ThingTypeUID PANEL_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, PARADOX_PANEL_THING_TYPE_ID); public static final ThingTypeUID PARTITION_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, PARTITION_THING_TYPE_ID); public static final ThingTypeUID ZONE_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, ZONE_THING_TYPE_ID); + public static final Set SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet( + Stream.of(COMMUNICATOR_THING_TYPE_UID, PANEL_THING_TYPE_UID, PARTITION_THING_TYPE_UID, ZONE_THING_TYPE_UID) + .collect(Collectors.toSet())); + // List of all Channel UIDs public static final String IP150_COMMUNICATION_COMMAND_CHANNEL_UID = "communicationCommand"; diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmHandlerFactory.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmHandlerFactory.java index a1ddc9a930248..34704f28700c3 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmHandlerFactory.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxAlarmHandlerFactory.java @@ -14,18 +14,22 @@ import static org.openhab.binding.paradoxalarm.internal.handlers.ParadoxAlarmBindingConstants.*; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.config.discovery.DiscoveryService; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.eclipse.smarthome.core.thing.ThingUID; import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; import org.eclipse.smarthome.core.thing.binding.ThingHandler; import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; +import org.openhab.binding.paradoxalarm.internal.discovery.ParadoxDiscoveryService; +import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +46,7 @@ public class ParadoxAlarmHandlerFactory extends BaseThingHandlerFactory { private final Logger logger = LoggerFactory.getLogger(ParadoxAlarmHandlerFactory.class); - private static final Set SUPPORTED_THING_TYPES_UIDS = new HashSet<>(Arrays - .asList(COMMUNICATOR_THING_TYPE_UID, PANEL_THING_TYPE_UID, PARTITION_THING_TYPE_UID, ZONE_THING_TYPE_UID)); + private final Map> discoveryServiceRegs = new HashMap<>(); @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { @@ -55,7 +58,11 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (COMMUNICATOR_THING_TYPE_UID.equals(thingTypeUID)) { logger.debug("createHandler(): ThingHandler created for {}", thingTypeUID); - return new ParadoxIP150BridgeHandler((Bridge) thing); + + ParadoxIP150BridgeHandler paradoxIP150BridgeHandler = new ParadoxIP150BridgeHandler((Bridge) thing); + registerDiscoveryService(paradoxIP150BridgeHandler); + + return paradoxIP150BridgeHandler; } else if (PANEL_THING_TYPE_UID.equals(thingTypeUID)) { logger.debug("createHandler(): ThingHandler created for {}", thingTypeUID); return new ParadoxPanelHandler(thing); @@ -70,4 +77,21 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { } return null; } + + private void registerDiscoveryService(ParadoxIP150BridgeHandler paradoxIP150BridgeHandler) { + ParadoxDiscoveryService discoveryService = new ParadoxDiscoveryService(paradoxIP150BridgeHandler); + ServiceRegistration serviceRegistration = bundleContext.registerService(DiscoveryService.class.getName(), + discoveryService, new Hashtable<>()); + this.discoveryServiceRegs.put(paradoxIP150BridgeHandler.getThing().getUID(), serviceRegistration); + } + + @Override + protected void removeHandler(ThingHandler thingHandler) { + if (thingHandler instanceof ParadoxIP150BridgeHandler) { + ServiceRegistration serviceReg = this.discoveryServiceRegs.remove(thingHandler.getThing().getUID()); + if (serviceReg != null) { + serviceReg.unregister(); + } + } + } } diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java index d84f39cebb6f4..e0bcbc0c62b2f 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java @@ -64,7 +64,8 @@ public class ParadoxIP150BridgeHandler extends BaseBridgeHandler implements IDat private final Logger logger = LoggerFactory.getLogger(ParadoxIP150BridgeHandler.class); - private static IParadoxCommunicator communicator; + private IParadoxCommunicator communicator; + private static ParadoxIP150BridgeConfiguration config; private @Nullable ScheduledFuture refreshCacheUpdateSchedule; @@ -270,4 +271,8 @@ private void cancelSchedule(@Nullable ScheduledFuture schedule) { } } + public IParadoxCommunicator getCommunicator() { + return communicator; + } + } diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java index 15b0af1126a80..dafc709dfc306 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java @@ -29,7 +29,7 @@ public abstract class Entity { public Entity(int id, String label) { this.id = id; - this.label = label; + this.label = label.trim(); logger.debug("Creating entity with label: {} and ID: {}", label, id); }