diff --git a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/ZmHandlerFactory.java b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/ZmHandlerFactory.java index 26704f290..00bf3d8cb 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/ZmHandlerFactory.java +++ b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/ZmHandlerFactory.java @@ -37,7 +37,7 @@ import org.osgi.service.component.annotations.Reference; * @author Mark Hilbush - Initial contribution */ @NonNullByDefault -@Component(configurationPid = "binding.zm", service = ThingHandlerFactory.class) +@Component(configurationPid = "binding.zoneminder", service = ThingHandlerFactory.class) public class ZmHandlerFactory extends BaseThingHandlerFactory { private final TimeZoneProvider timeZoneProvider; diff --git a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/config/ZmBridgeConfig.java b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/config/ZmBridgeConfig.java index b1b170b11..7e4d37438 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/config/ZmBridgeConfig.java +++ b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/config/ZmBridgeConfig.java @@ -50,16 +50,6 @@ public class ZmBridgeConfig { */ public @Nullable Integer refreshInterval; - /** - * Enable/disable monitor discovery - */ - public @Nullable Boolean discoveryEnabled; - - /** - * Frequency at which the binding will try to discover monitors - */ - public @Nullable Integer discoveryInterval; - /** * Alarm duration set on monitor things when they're discovered */ @@ -70,6 +60,11 @@ public class ZmBridgeConfig { */ public @Nullable Integer defaultImageRefreshInterval; + /** + * Enable/disable monitor discovery + */ + public Boolean discoveryEnabled = Boolean.TRUE; + /** * Zoneminder user name */ diff --git a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/discovery/MonitorDiscoveryService.java b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/discovery/MonitorDiscoveryService.java index a7429c16b..4fc46d2fe 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/discovery/MonitorDiscoveryService.java +++ b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/discovery/MonitorDiscoveryService.java @@ -17,6 +17,8 @@ import static org.openhab.binding.zoneminder.internal.ZmBindingConstants.*; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -44,17 +46,32 @@ public class MonitorDiscoveryService extends AbstractDiscoveryService implements private final Logger logger = LoggerFactory.getLogger(MonitorDiscoveryService.class); - private @Nullable ZmBridgeHandler bridgeHandler; + private static final int DISCOVERY_INTERVAL_SECONDS = 300; + private static final int DISCOVERY_INITIAL_DELAY_SECONDS = 10; + private static final int DISCOVERY_TIMEOUT_SECONDS = 6; + + private @NonNullByDefault({}) ZmBridgeHandler bridgeHandler; + + private @Nullable Future discoveryJob; public MonitorDiscoveryService() { - super(30); + super(SUPPORTED_MONITOR_THING_TYPES_UIDS, DISCOVERY_TIMEOUT_SECONDS, true); + } + + @Override + public void activate() { + super.activate(null); + } + + @Override + public void deactivate() { + super.deactivate(); } @Override public void setThingHandler(@Nullable ThingHandler handler) { if (handler instanceof ZmBridgeHandler) { - ((ZmBridgeHandler) handler).setDiscoveryService(this); - this.bridgeHandler = (ZmBridgeHandler) handler; + bridgeHandler = (ZmBridgeHandler) handler; } } @@ -63,66 +80,69 @@ public class MonitorDiscoveryService extends AbstractDiscoveryService implements return bridgeHandler; } - @Override - public void activate() { - } - - @Override - public void deactivate() { - } - @Override public Set getSupportedThingTypes() { return SUPPORTED_MONITOR_THING_TYPES_UIDS; } @Override - public void startBackgroundDiscovery() { - logger.trace("Discovery: Performing background discovery scan for {}", getBridgeUID()); - discoverMonitors(); + protected void startBackgroundDiscovery() { + Future localDiscoveryJob = discoveryJob; + if (localDiscoveryJob == null || localDiscoveryJob.isCancelled()) { + logger.debug("ZoneminderDiscovery: Starting background discovery job"); + discoveryJob = scheduler.scheduleWithFixedDelay(this::backgroundDiscoverMonitors, + DISCOVERY_INITIAL_DELAY_SECONDS, DISCOVERY_INTERVAL_SECONDS, TimeUnit.SECONDS); + } + } + + @Override + protected void stopBackgroundDiscovery() { + Future localDiscoveryJob = discoveryJob; + if (localDiscoveryJob != null) { + logger.debug("ZoneminderDiscovery: Stopping background discovery job"); + localDiscoveryJob.cancel(true); + discoveryJob = null; + } } @Override public void startScan() { - logger.debug("Discovery: Starting monitor discovery scan for {}", getBridgeUID()); + logger.debug("ZoneminderDiscovery: Running discovery scan"); discoverMonitors(); } - private @Nullable ThingUID getBridgeUID() { - ZmBridgeHandler localBridgeHandler = bridgeHandler; - return localBridgeHandler != null ? localBridgeHandler.getThing().getUID() : null; + private void backgroundDiscoverMonitors() { + if (!bridgeHandler.isBackgroundDiscoveryEnabled()) { + return; + } + logger.debug("ZoneminderDiscovery: Running background discovery scan"); + discoverMonitors(); } private synchronized void discoverMonitors() { - ZmBridgeHandler localBridgeHandler = bridgeHandler; - ThingUID bridgeUID = getBridgeUID(); - if (localBridgeHandler != null && bridgeUID != null) { - Integer alarmDuration = localBridgeHandler.getDefaultAlarmDuration(); - Integer imageRefreshInterval = localBridgeHandler.getDefaultImageRefreshInterval(); - for (Monitor monitor : localBridgeHandler.getSavedMonitors()) { - String id = monitor.getId(); - String name = monitor.getName(); - ThingUID thingUID = new ThingUID(UID_MONITOR, bridgeUID, monitor.getId()); - Map properties = new HashMap<>(); - properties.put(CONFIG_MONITOR_ID, id); - properties.put(CONFIG_ALARM_DURATION, alarmDuration); - if (imageRefreshInterval != null) { - properties.put(CONFIG_IMAGE_REFRESH_INTERVAL, imageRefreshInterval); - } - thingDiscovered(createDiscoveryResult(thingUID, bridgeUID, id, name, properties)); - logger.trace("Discovery: Monitor with id '{}' and name '{}' added to Inbox with UID '{}'", - monitor.getId(), monitor.getName(), thingUID); + ThingUID bridgeUID = bridgeHandler.getThing().getUID(); + Integer alarmDuration = bridgeHandler.getDefaultAlarmDuration(); + Integer imageRefreshInterval = bridgeHandler.getDefaultImageRefreshInterval(); + for (Monitor monitor : bridgeHandler.getSavedMonitors()) { + String id = monitor.getId(); + String name = monitor.getName(); + ThingUID thingUID = new ThingUID(UID_MONITOR, bridgeUID, monitor.getId()); + Map properties = new HashMap<>(); + properties.put(CONFIG_MONITOR_ID, id); + properties.put(CONFIG_ALARM_DURATION, alarmDuration); + if (imageRefreshInterval != null) { + properties.put(CONFIG_IMAGE_REFRESH_INTERVAL, imageRefreshInterval); } + thingDiscovered(createDiscoveryResult(thingUID, bridgeUID, id, name, properties)); + logger.debug("ZoneminderDiscovery: Monitor with id '{}' and name '{}' added to Inbox with UID '{}'", + monitor.getId(), monitor.getName(), thingUID); } } private DiscoveryResult createDiscoveryResult(ThingUID monitorUID, ThingUID bridgeUID, String id, String name, Map properties) { return DiscoveryResultBuilder.create(monitorUID).withProperties(properties).withBridge(bridgeUID) - .withLabel(buildLabel(name)).withRepresentationProperty(CONFIG_MONITOR_ID).build(); - } - - private String buildLabel(String name) { - return String.format("Zoneminder Monitor %s", name); + .withLabel(String.format("Zoneminder Monitor %s", name)).withRepresentationProperty(CONFIG_MONITOR_ID) + .build(); } } diff --git a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmBridgeHandler.java b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmBridgeHandler.java index d5e8bbc3f..4a3384b86 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmBridgeHandler.java +++ b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmBridgeHandler.java @@ -28,7 +28,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -81,14 +80,8 @@ import com.google.gson.JsonSyntaxException; @NonNullByDefault public class ZmBridgeHandler extends BaseBridgeHandler { - private static final int REFRESH_INTERVAL_SECONDS = 1; - private static final int REFRESH_STARTUP_DELAY_SECONDS = 3; - - private static final int MONITORS_INTERVAL_SECONDS = 5; - private static final int MONITORS_INITIAL_DELAY_SECONDS = 3; - - private static final int DISCOVERY_INTERVAL_SECONDS = 300; - private static final int DISCOVERY_INITIAL_DELAY_SECONDS = 10; + private static final int MONITOR_REFRESH_INTERVAL_SECONDS = 10; + private static final int MONITOR_REFRESH_STARTUP_DELAY_SECONDS = 5; private static final int API_TIMEOUT_MSEC = 10000; @@ -104,10 +97,6 @@ public class ZmBridgeHandler extends BaseBridgeHandler { private final Logger logger = LoggerFactory.getLogger(ZmBridgeHandler.class); private @Nullable Future refreshMonitorsJob; - private final AtomicInteger monitorsCounter = new AtomicInteger(); - - private @Nullable MonitorDiscoveryService discoveryService; - private final AtomicInteger discoveryCounter = new AtomicInteger(); private List savedMonitors = new ArrayList<>(); @@ -115,9 +104,8 @@ public class ZmBridgeHandler extends BaseBridgeHandler { private boolean useSSL; private @Nullable String portNumber; private String urlPath = DEFAULT_URL_PATH; - private int monitorsInterval; - private int discoveryInterval; - private boolean discoveryEnabled; + private int monitorRefreshInterval; + private boolean backgroundDiscoveryEnabled; private int defaultAlarmDuration; private @Nullable Integer defaultImageRefreshInterval; @@ -144,17 +132,15 @@ public class ZmBridgeHandler extends BaseBridgeHandler { Integer value; value = config.refreshInterval; - monitorsInterval = value == null ? MONITORS_INTERVAL_SECONDS : value; - - value = config.discoveryInterval; - discoveryInterval = value == null ? DISCOVERY_INTERVAL_SECONDS : value; + monitorRefreshInterval = value == null ? MONITOR_REFRESH_INTERVAL_SECONDS : value; value = config.defaultAlarmDuration; defaultAlarmDuration = value == null ? DEFAULT_ALARM_DURATION_SECONDS : value; defaultImageRefreshInterval = config.defaultImageRefreshInterval; - discoveryEnabled = config.discoveryEnabled == null ? false : config.discoveryEnabled.booleanValue(); + backgroundDiscoveryEnabled = config.discoveryEnabled; + logger.debug("Bridge: Background discovery is {}", backgroundDiscoveryEnabled == true ? "ENABLED" : "DISABLED"); host = config.host; useSSL = config.useSSL.booleanValue(); @@ -222,12 +208,8 @@ public class ZmBridgeHandler extends BaseBridgeHandler { return Collections.singleton(MonitorDiscoveryService.class); } - public void setDiscoveryService(MonitorDiscoveryService discoveryService) { - this.discoveryService = discoveryService; - } - - public boolean isDiscoveryEnabled() { - return discoveryEnabled; + public boolean isBackgroundDiscoveryEnabled() { + return backgroundDiscoveryEnabled; } public Integer getDefaultAlarmDuration() { @@ -571,40 +553,14 @@ public class ZmBridgeHandler extends BaseBridgeHandler { return false; } - /* - * The refresh job is executed every second - * - updates the monitor handlers every monitorsInterval seconds, and - * - runs the monitor discovery every discoveryInterval seconds - */ - private void refresh() { - refreshMonitors(); - discoverMonitors(); - } - @SuppressWarnings("null") private void refreshMonitors() { - if (monitorsCounter.getAndDecrement() == 0) { - monitorsCounter.set(monitorsInterval); - List monitors = getMonitors(); - savedMonitors = monitors; - for (Monitor monitor : monitors) { - ZmMonitorHandler handler = monitorHandlers.get(monitor.getId()); - if (handler != null) { - handler.updateStatus(monitor); - } - } - } - } - - private void discoverMonitors() { - if (isDiscoveryEnabled()) { - if (discoveryCounter.getAndDecrement() == 0) { - discoveryCounter.set(discoveryInterval); - MonitorDiscoveryService localDiscoveryService = discoveryService; - if (localDiscoveryService != null) { - logger.trace("Bridge: Running monitor discovery"); - localDiscoveryService.startBackgroundDiscovery(); - } + List monitors = getMonitors(); + savedMonitors = monitors; + for (Monitor monitor : monitors) { + ZmMonitorHandler handler = monitorHandlers.get(monitor.getId()); + if (handler != null) { + handler.updateStatus(monitor); } } } @@ -612,10 +568,8 @@ public class ZmBridgeHandler extends BaseBridgeHandler { private void scheduleRefreshJob() { logger.debug("Bridge: Scheduling monitors refresh job"); cancelRefreshJob(); - monitorsCounter.set(MONITORS_INITIAL_DELAY_SECONDS); - discoveryCounter.set(DISCOVERY_INITIAL_DELAY_SECONDS); - refreshMonitorsJob = scheduler.scheduleWithFixedDelay(this::refresh, REFRESH_STARTUP_DELAY_SECONDS, - REFRESH_INTERVAL_SECONDS, TimeUnit.SECONDS); + refreshMonitorsJob = scheduler.scheduleWithFixedDelay(this::refreshMonitors, + MONITOR_REFRESH_STARTUP_DELAY_SECONDS, monitorRefreshInterval, TimeUnit.SECONDS); } private void cancelRefreshJob() { @@ -623,6 +577,7 @@ public class ZmBridgeHandler extends BaseBridgeHandler { if (localRefreshThermostatsJob != null) { localRefreshThermostatsJob.cancel(true); logger.debug("Bridge: Canceling monitors refresh job"); + refreshMonitorsJob = null; } } } diff --git a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmMonitorHandler.java b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmMonitorHandler.java index 629d95f33..ea41cf34e 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmMonitorHandler.java +++ b/bundles/org.openhab.binding.zoneminder/src/main/java/org/openhab/binding/zoneminder/internal/handler/ZmMonitorHandler.java @@ -254,6 +254,7 @@ public class ZmMonitorHandler extends BaseThingHandler { } private void startImageRefreshJob() { + stopImageRefreshJob(); Integer interval = imageRefreshIntervalSeconds; if (interval != null) { long delay = getRandomDelay(interval); diff --git a/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/config/config.xml index 5f66f9d9c..18227c978 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/config/config.xml @@ -14,31 +14,8 @@ - - - Interval in seconds at which monitor status is updated - 5 - - - - Enable/disable automatic discovery - true - - - - Specifies time in seconds in which the binding will attempt to discover monitors - 300 - - - - Duration in seconds after which the alarm will be turned off - 60 - - - - Interval in seconds at which monitor image snapshot will be updated - + + ZoneMinder server name or IP address @@ -58,6 +35,30 @@ URL path (Default is /zm. Use / if Zoneminder installed under the root directory) /zm + + + + + Interval in seconds at which monitor status is updated + 5 + + + + Duration in seconds after which the alarm will be turned off + 60 + + + + Interval in seconds at which monitor image snapshot will be updated + + + + Enable/disable background discovery of monitors + true + + + User name (if authentication enabled in ZoneMinder) diff --git a/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/thing/thing-types.xml index 8dcb34510..a9e12479e 100644 --- a/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.zoneminder/src/main/resources/OH-INF/thing/thing-types.xml @@ -73,6 +73,9 @@ + + monitorId +