Skip to content

Commit

Permalink
Merge branch 'main' into enriched_actions_api
Browse files Browse the repository at this point in the history
  • Loading branch information
lolodomo committed Oct 16, 2024
2 parents 6bc655b + af35487 commit 8f99ebc
Show file tree
Hide file tree
Showing 55 changed files with 814 additions and 143 deletions.
2 changes: 1 addition & 1 deletion bom/compile/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@
<dependency>
<groupId>de.focus-shift</groupId>
<artifactId>jollyday-jackson</artifactId>
<version>0.30.0</version>
<version>0.32.0</version>
<scope>compile</scope>
</dependency>

Expand Down
6 changes: 3 additions & 3 deletions bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
<version>33.3.0-jre</version>
<scope>compile</scope>
</dependency>

Expand All @@ -808,7 +808,7 @@
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.172</version>
<version>4.8.174</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -950,7 +950,7 @@
<dependency>
<groupId>de.focus-shift</groupId>
<artifactId>jollyday-jackson</artifactId>
<version>0.30.0</version>
<version>0.32.0</version>
<scope>compile</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

import javax.script.Compilable;
import javax.script.CompiledScript;
Expand Down Expand Up @@ -210,15 +212,29 @@ protected void resetExecutionContext(ScriptEngine engine, Map<String, ?> context
protected @Nullable Object eval(ScriptEngine engine, String script) {
try {
if (compiledScript.isPresent()) {
if (engine instanceof Lock lock && !lock.tryLock(1, TimeUnit.MINUTES)) {
logger.error("Failed to acquire lock within one minute for script module of rule with UID '{}'",
ruleUID);
return null;
}
logger.debug("Executing pre-compiled script of rule with UID '{}'", ruleUID);
return compiledScript.get().eval(engine.getContext());
try {
return compiledScript.get().eval(engine.getContext());
} finally { // Make sure that Lock is unlocked regardless of an exception being thrown or not to avoid
// deadlocks
if (engine instanceof Lock lock) {
lock.unlock();
}
}
}
logger.debug("Executing script of rule with UID '{}'", ruleUID);
return engine.eval(script);
} catch (ScriptException e) {
logger.error("Script execution of rule with UID '{}' failed: {}", ruleUID, e.getMessage(),
logger.isDebugEnabled() ? e : null);
return null;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,10 @@ public void filteredTimeSeriesTest() throws TransformationException {

private TimeSeries createTimeSeries(State... states) {
TimeSeries timeSeries = new TimeSeries(TimeSeries.Policy.ADD);
Instant instant = Instant.now();
for (State state : states) {
timeSeries.add(Instant.now(), state);
timeSeries.add(instant, state);
instant = instant.plusMillis(100);
}
return timeSeries;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ module-type.timer.DateTimeTrigger.config.timeOnly.label = זמן בלבד
module-type.timer.DateTimeTrigger.config.timeOnly.description = מציין אם יש להשוות רק את השעה של הפריט או את התאריך והשעה.
module-type.timer.DateTimeTrigger.config.timeOnly.option.true = כן
module-type.timer.DateTimeTrigger.config.timeOnly.option.false = לא
module-type.timer.DateTimeTrigger.config.offset.label = היסט
module-type.timer.DateTimeTrigger.config.offset.description = הקיזוז בשניות כדי להוסיף לזמן הפריט.

# timer.DayOfWeekCondition

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ options_violated=Verdien {0} samsvarer ikke med tillatte parameteralternativer.
multiple_limit_violated=Kun {0} elementer er tillatt mens {1} er angitt.

bridge_not_configured=Konfigurasjon av en bro er obligatorisk.
type_description_missing=Typebeskivelsen for {0} for {1} ble ikke funnet, vi sjekket også tilstedeværelsen tidligere.
config_description_missing=Typebeskivelsen for {0} for {1} ble ikke funnet, selv om vi sjekket tilstedeværelsen tidligere.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* @author Kai Kreuzer - Refactored API
* @author Dennis Nobel - Added background discovery configuration through Configuration Admin
* @author Andre Fuechsel - Added removeOlderResults
* @author Laurent Garnier - Added discovery with an optional input parameter
*/
@NonNullByDefault
public abstract class AbstractDiscoveryService implements DiscoveryService {
Expand All @@ -64,6 +65,9 @@ public abstract class AbstractDiscoveryService implements DiscoveryService {

private boolean backgroundDiscoveryEnabled;

private @Nullable String scanInputLabel;
private @Nullable String scanInputDescription;

private final Map<ThingUID, DiscoveryResult> cachedResults = new HashMap<>();

private final Set<ThingTypeUID> supportedThingTypes;
Expand All @@ -84,20 +88,44 @@ public abstract class AbstractDiscoveryService implements DiscoveryService {
* service automatically stops its forced discovery process (>= 0).
* @param backgroundDiscoveryEnabledByDefault defines, whether the default for this discovery service is to
* enable background discovery or not.
* @param scanInputLabel the label of the optional input parameter to start the discovery or null if no input
* parameter supported
* @param scanInputDescription the description of the optional input parameter to start the discovery or null if no
* input parameter supported
* @throws IllegalArgumentException if {@code timeout < 0}
*/
protected AbstractDiscoveryService(@Nullable Set<ThingTypeUID> supportedThingTypes, int timeout,
boolean backgroundDiscoveryEnabledByDefault) throws IllegalArgumentException {
boolean backgroundDiscoveryEnabledByDefault, @Nullable String scanInputLabel,
@Nullable String scanInputDescription) throws IllegalArgumentException {
if (timeout < 0) {
throw new IllegalArgumentException("The timeout must be >= 0!");
}
this.supportedThingTypes = supportedThingTypes == null ? Set.of() : Set.copyOf(supportedThingTypes);
this.timeout = timeout;
this.backgroundDiscoveryEnabled = backgroundDiscoveryEnabledByDefault;
this.scanInputLabel = scanInputLabel;
this.scanInputDescription = scanInputDescription;
}

/**
* Creates a new instance of this class with the specified parameters and no input parameter supported to start the
* discovery.
*
* @param supportedThingTypes the list of Thing types which are supported (can be null)
* @param timeout the discovery timeout in seconds after which the discovery
* service automatically stops its forced discovery process (>= 0).
* @param backgroundDiscoveryEnabledByDefault defines, whether the default for this discovery service is to
* enable background discovery or not.
* @throws IllegalArgumentException if {@code timeout < 0}
*/
protected AbstractDiscoveryService(@Nullable Set<ThingTypeUID> supportedThingTypes, int timeout,
boolean backgroundDiscoveryEnabledByDefault) throws IllegalArgumentException {
this(supportedThingTypes, timeout, backgroundDiscoveryEnabledByDefault, null, null);
}

/**
* Creates a new instance of this class with the specified parameters and background discovery enabled.
* Creates a new instance of this class with the specified parameters and background discovery enabled
* and no input parameter supported to start the discovery.
*
* @param supportedThingTypes the list of Thing types which are supported (can be null)
* @param timeout the discovery timeout in seconds after which the discovery service
Expand All @@ -111,7 +139,8 @@ protected AbstractDiscoveryService(@Nullable Set<ThingTypeUID> supportedThingTyp
}

/**
* Creates a new instance of this class with the specified parameters and background discovery enabled.
* Creates a new instance of this class with the specified parameters and background discovery enabled
* and no input parameter supported to start the discovery.
*
* @param timeout the discovery timeout in seconds after which the discovery service
* automatically stops its forced discovery process (>= 0).
Expand All @@ -133,6 +162,21 @@ public Set<ThingTypeUID> getSupportedThingTypes() {
return supportedThingTypes;
}

@Override
public boolean isScanInputSupported() {
return getScanInputLabel() != null && getScanInputDescription() != null;
}

@Override
public @Nullable String getScanInputLabel() {
return scanInputLabel;
}

@Override
public @Nullable String getScanInputDescription() {
return scanInputDescription;
}

/**
* Returns the amount of time in seconds after which the discovery service automatically
* stops its forced discovery process.
Expand Down Expand Up @@ -168,7 +212,16 @@ public void removeDiscoveryListener(@Nullable DiscoveryListener listener) {
}

@Override
public synchronized void startScan(@Nullable ScanListener listener) {
public void startScan(@Nullable ScanListener listener) {
startScanInternal(null, listener);
}

@Override
public void startScan(String input, @Nullable ScanListener listener) {
startScanInternal(input, listener);
}

private synchronized void startScanInternal(@Nullable String input, @Nullable ScanListener listener) {
synchronized (this) {
// we first stop any currently running scan and its scheduled stop
// call
Expand All @@ -194,7 +247,11 @@ public synchronized void startScan(@Nullable ScanListener listener) {
timestampOfLastScan = Instant.now();

try {
startScan();
if (isScanInputSupported() && input != null) {
startScan(input);
} else {
startScan();
}
} catch (Exception ex) {
scheduledStop = this.scheduledStop;
if (scheduledStop != null) {
Expand Down Expand Up @@ -232,6 +289,11 @@ public synchronized void abortScan() {
*/
protected abstract void startScan();

// An abstract method would have required a change in all existing bindings implementing a DiscoveryService
protected void startScan(String input) {
logger.warn("Discovery with input parameter not implemented by service '{}'!", this.getClass().getName());
}

/**
* This method cleans up after a scan, i.e. it removes listeners and other required operations.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* It handles the injection of the {@link ThingHandler}
*
* @author Jan N. Klug - Initial contribution
* @author Laurent Garnier - Added discovery with an optional input parameter
*/
@NonNullByDefault
public abstract class AbstractThingHandlerDiscoveryService<T extends ThingHandler> extends AbstractDiscoveryService
Expand All @@ -45,12 +46,18 @@ public abstract class AbstractThingHandlerDiscoveryService<T extends ThingHandle
protected @NonNullByDefault({}) T thingHandler = (@NonNull T) null;

protected AbstractThingHandlerDiscoveryService(Class<T> thingClazz, @Nullable Set<ThingTypeUID> supportedThingTypes,
int timeout, boolean backgroundDiscoveryEnabledByDefault) throws IllegalArgumentException {
super(supportedThingTypes, timeout, backgroundDiscoveryEnabledByDefault);
int timeout, boolean backgroundDiscoveryEnabledByDefault, @Nullable String scanInputLabel,
@Nullable String scanInputDescription) throws IllegalArgumentException {
super(supportedThingTypes, timeout, backgroundDiscoveryEnabledByDefault, scanInputLabel, scanInputDescription);
this.thingClazz = thingClazz;
this.backgroundDiscoveryEnabled = backgroundDiscoveryEnabledByDefault;
}

protected AbstractThingHandlerDiscoveryService(Class<T> thingClazz, @Nullable Set<ThingTypeUID> supportedThingTypes,
int timeout, boolean backgroundDiscoveryEnabledByDefault) throws IllegalArgumentException {
this(thingClazz, supportedThingTypes, timeout, backgroundDiscoveryEnabledByDefault, null, null);
}

protected AbstractThingHandlerDiscoveryService(Class<T> thingClazz, @Nullable Set<ThingTypeUID> supportedThingTypes,
int timeout) throws IllegalArgumentException {
this(thingClazz, supportedThingTypes, timeout, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* @author Michael Grammling - Initial contribution
* @author Kai Kreuzer - Refactored API
* @author Dennis Nobel - Added background discovery configuration through Configuration Admin
* @author Laurent Garnier - Added discovery with an optional input parameter
*
* @see DiscoveryListener
* @see DiscoveryServiceRegistry
Expand All @@ -60,6 +61,31 @@ public interface DiscoveryService {
*/
Collection<ThingTypeUID> getSupportedThingTypes();

/**
* Returns {@code true} if the discovery supports an optional input parameter to run, otherwise {@code false}.
*
* @return true if the discovery supports an optional input parameter to run, otherwise false
*/
boolean isScanInputSupported();

/**
* Returns the label of the supported input parameter to start the discovery.
*
* @return the label of the supported input parameter to start the discovery or null if input parameter not
* supported
*/
@Nullable
String getScanInputLabel();

/**
* Returns the description of the supported input parameter to start the discovery.
*
* @return the description of the supported input parameter to start the discovery or null if input parameter not
* supported
*/
@Nullable
String getScanInputDescription();

/**
* Returns the amount of time in seconds after which an active scan ends.
*
Expand Down Expand Up @@ -87,6 +113,20 @@ public interface DiscoveryService {
*/
void startScan(@Nullable ScanListener listener);

/**
* Triggers this service to start an active scan for new devices using an input parameter for that.<br>
* This method must not block any calls such as {@link #abortScan()} and
* must return fast.
* <p>
* If started, any registered {@link DiscoveryListener} must be notified about {@link DiscoveryResult}s.
* <p>
* If there is already a scan running, it is aborted and a new scan is triggered.
*
* @param input an input parameter to be used during discovery scan
* @param listener a listener that is notified about errors or termination of the scan
*/
void startScan(String input, @Nullable ScanListener listener);

/**
* Stops an active scan for devices.<br>
* This method must not block any calls such as {@link #startScan} and must
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.openhab.core.config.discovery;

import java.util.List;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -29,6 +30,7 @@
*
* @author Michael Grammling - Initial contribution
* @author Ivaylo Ivanov - Added getMaxScanTimeout
* @author Laurent Garnier - Added discovery with an optional input parameter
*
* @see DiscoveryService
* @see DiscoveryListener
Expand All @@ -44,6 +46,7 @@ public interface DiscoveryServiceRegistry {
*
* @param thingTypeUID the Thing type UID pointing to collection of discovery
* services to be forced to start a discovery
* @param input an optional input parameter to be used during discovery scan, can be null.
* @param listener a callback to inform about errors or termination, can be null.
* If more than one discovery service is started, the {@link ScanListener#onFinished()} callback is
* called after all
Expand All @@ -54,7 +57,7 @@ public interface DiscoveryServiceRegistry {
* @return true if a t least one discovery service could be found and forced
* to start a discovery, otherwise false
*/
boolean startScan(ThingTypeUID thingTypeUID, @Nullable ScanListener listener);
boolean startScan(ThingTypeUID thingTypeUID, @Nullable String input, @Nullable ScanListener listener);

/**
* Forces the associated {@link DiscoveryService}s to start a discovery for
Expand All @@ -65,6 +68,7 @@ public interface DiscoveryServiceRegistry {
*
* @param bindingId the binding id pointing to one or more discovery services to
* be forced to start a discovery
* @param input an optional input parameter to be used during discovery scan, can be null.
* @param listener a callback to inform about errors or termination, can be null.
* If more than one discovery service is started, the {@link ScanListener#onFinished()} callback is
* called after all
Expand All @@ -75,7 +79,7 @@ public interface DiscoveryServiceRegistry {
* @return true if a t least one discovery service could be found and forced
* to start a discovery, otherwise false
*/
boolean startScan(String bindingId, @Nullable ScanListener listener);
boolean startScan(String bindingId, @Nullable String input, @Nullable ScanListener listener);

/**
* Aborts a started discovery on all {@link DiscoveryService}s for the given
Expand Down Expand Up @@ -163,6 +167,13 @@ public interface DiscoveryServiceRegistry {
*/
List<String> getSupportedBindings();

/**
* Returns the list of all {@link DiscoveryService}s, that discover thing types of the given binding id.
*
* @return list of discovery services, that discover thing types of the given binding id
*/
Set<DiscoveryService> getDiscoveryServices(String bindingId) throws IllegalStateException;

/**
* Returns the maximum discovery timeout from all discovery services registered for the specified thingTypeUID
*
Expand Down
Loading

0 comments on commit 8f99ebc

Please sign in to comment.