mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 07:02:02 +01:00
Updated license headers
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
parent
734c3b06ff
commit
6f9c605eeb
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
@ -10,7 +10,6 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
|
||||
@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
|
||||
package org.openhab.automation.groovyscripting.internal;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
@ -10,7 +10,6 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
|
||||
@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
|
||||
package org.openhab.automation.jythonscripting;
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Realizes an first-order FIR low pass filter. To keep code complexity low, it is implemented as moving average (all
|
||||
* FIR coefficients are set to normalized ones).
|
||||
*
|
||||
* The exponential decaying function is used for the calculation (see https://en.wikipedia.org/wiki/Time_constant). That
|
||||
* means the output value is approx. 63% of the input value after one time constant and approx. 99% after 5 time
|
||||
* constants.
|
||||
*
|
||||
* @author Fabian Wolter - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LowpassFilter {
|
||||
/**
|
||||
* Executes one low pass filter step.
|
||||
*
|
||||
* @param lastOutput the current filter value (result of the last invocation)
|
||||
* @param newValue the just sampled value
|
||||
* @param timeQuotient quotient of the current time and the time constant
|
||||
* @return the new filter value
|
||||
*/
|
||||
public static double calculate(double lastOutput, double newValue, double timeQuotient) {
|
||||
double output = lastOutput * Math.exp(-timeQuotient);
|
||||
output += newValue * (1 - Math.exp(-timeQuotient));
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
*
|
||||
* Constants for PID controller.
|
||||
*
|
||||
* @author Fabian Wolter - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerConstants {
|
||||
public static final String AUTOMATION_NAME = "pidcontroller";
|
||||
public static final String CONFIG_INPUT_ITEM = "input";
|
||||
public static final String CONFIG_SETPOINT_ITEM = "setpoint";
|
||||
public static final String CONFIG_OUTPUT_LOWER_LIMIT = "outputLowerLimit";
|
||||
public static final String CONFIG_OUTPUT_UPPER_LIMIT = "outputUpperLimit";
|
||||
public static final String CONFIG_LOOP_TIME = "loopTime";
|
||||
public static final String CONFIG_KP_GAIN = "kp";
|
||||
public static final String CONFIG_KI_GAIN = "ki";
|
||||
public static final String CONFIG_KD_GAIN = "kd";
|
||||
public static final String CONFIG_KD_TIMECONSTANT = "kdTimeConstant";
|
||||
public static final String P_INSPECTOR = "pInspector";
|
||||
public static final String I_INSPECTOR = "iInspector";
|
||||
public static final String D_INSPECTOR = "dInspector";
|
||||
public static final String E_INSPECTOR = "eInspector";
|
||||
public static final String OUTPUT = "output";
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
*
|
||||
* Common Exception for PID controller.
|
||||
*
|
||||
* @author Fabian Wolter - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDException extends Exception {
|
||||
private static final long serialVersionUID = -3029834022610530982L;
|
||||
|
||||
public PIDException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.factory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerActionHandler;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerTriggerHandler;
|
||||
import org.openhab.core.automation.Action;
|
||||
import org.openhab.core.automation.Module;
|
||||
import org.openhab.core.automation.Trigger;
|
||||
import org.openhab.core.automation.handler.BaseModuleHandlerFactory;
|
||||
import org.openhab.core.automation.handler.ModuleHandler;
|
||||
import org.openhab.core.automation.handler.ModuleHandlerFactory;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@Component(service = ModuleHandlerFactory.class, configurationPid = "action.pidcontroller")
|
||||
@NonNullByDefault
|
||||
public class PIDControllerModuleHandlerFactory extends BaseModuleHandlerFactory {
|
||||
private static final Collection<String> TYPES = Set.of(PIDControllerTriggerHandler.MODULE_TYPE_ID,
|
||||
PIDControllerActionHandler.MODULE_TYPE_ID);
|
||||
private ItemRegistry itemRegistry;
|
||||
private EventPublisher eventPublisher;
|
||||
private BundleContext bundleContext;
|
||||
|
||||
@Activate
|
||||
public PIDControllerModuleHandlerFactory(@Reference ItemRegistry itemRegistry,
|
||||
@Reference EventPublisher eventPublisher, BundleContext bundleContext) {
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.bundleContext = bundleContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getTypes() {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ModuleHandler internalCreate(Module module, String ruleUID) {
|
||||
switch (module.getTypeUID()) {
|
||||
case PIDControllerTriggerHandler.MODULE_TYPE_ID:
|
||||
return new PIDControllerTriggerHandler((Trigger) module, itemRegistry, eventPublisher, bundleContext);
|
||||
case PIDControllerActionHandler.MODULE_TYPE_ID:
|
||||
return new PIDControllerActionHandler((Action) module, itemRegistry, eventPublisher);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.automation.pidcontroller.internal.LowpassFilter;
|
||||
|
||||
/**
|
||||
* The {@link PIDController} provides the necessary methods for retrieving part(s) of the PID calculations
|
||||
* and it provides the method for the overall PID calculations. It also resets the PID controller
|
||||
*
|
||||
* @author George Erhan - Initial contribution
|
||||
* @author Hilbrand Bouwkamp - Adapted for new rule engine
|
||||
* @author Fabian Wolter - Add T1 to D part, add debugging ability for PID values
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class PIDController {
|
||||
private final double outputLowerLimit;
|
||||
private final double outputUpperLimit;
|
||||
|
||||
private double integralResult;
|
||||
private double derivativeResult;
|
||||
private double previousError;
|
||||
private double output;
|
||||
|
||||
private double kp;
|
||||
private double ki;
|
||||
private double kd;
|
||||
private double derivativeTimeConstantSec;
|
||||
|
||||
public PIDController(double outputLowerLimit, double outputUpperLimit, double kpAdjuster, double kiAdjuster,
|
||||
double kdAdjuster, double derivativeTimeConstantSec) {
|
||||
this.outputLowerLimit = outputLowerLimit;
|
||||
this.outputUpperLimit = outputUpperLimit;
|
||||
this.kp = kpAdjuster;
|
||||
this.ki = kiAdjuster;
|
||||
this.kd = kdAdjuster;
|
||||
this.derivativeTimeConstantSec = derivativeTimeConstantSec;
|
||||
}
|
||||
|
||||
public PIDOutputDTO calculate(double input, double setpoint, long lastInvocationMs) {
|
||||
final double lastInvocationSec = lastInvocationMs / 1000d;
|
||||
final double error = setpoint - input;
|
||||
|
||||
// derivative T1 calculation
|
||||
final double timeQuotient = lastInvocationSec / derivativeTimeConstantSec;
|
||||
if (derivativeTimeConstantSec != 0) {
|
||||
derivativeResult = LowpassFilter.calculate(derivativeResult, error - previousError, timeQuotient);
|
||||
previousError = error;
|
||||
}
|
||||
|
||||
// integral calculation
|
||||
integralResult += error * lastInvocationSec;
|
||||
// limit to output limits
|
||||
if (ki != 0) {
|
||||
final double maxIntegral = outputUpperLimit / ki;
|
||||
final double minIntegral = outputLowerLimit / ki;
|
||||
integralResult = Math.min(maxIntegral, Math.max(minIntegral, integralResult));
|
||||
}
|
||||
|
||||
// calculate parts
|
||||
final double proportionalPart = kp * error;
|
||||
final double integralPart = ki * integralResult;
|
||||
final double derivativePart = kd * derivativeResult;
|
||||
output = proportionalPart + integralPart + derivativePart;
|
||||
|
||||
// limit output value
|
||||
output = Math.min(outputUpperLimit, Math.max(outputLowerLimit, output));
|
||||
|
||||
return new PIDOutputDTO(output, proportionalPart, integralPart, derivativePart, error);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.handler;
|
||||
|
||||
import static org.openhab.automation.pidcontroller.internal.PIDControllerConstants.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.Action;
|
||||
import org.openhab.core.automation.handler.ActionHandler;
|
||||
import org.openhab.core.automation.handler.BaseModuleHandler;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.items.events.ItemCommandEvent;
|
||||
import org.openhab.core.items.events.ItemEventFactory;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
* @author Fabian Wolter - Add PID debugging items
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerActionHandler extends BaseModuleHandler<Action> implements ActionHandler {
|
||||
public static final String MODULE_TYPE_ID = AUTOMATION_NAME + ".action";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(PIDControllerActionHandler.class);
|
||||
|
||||
private ItemRegistry itemRegistry;
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
public PIDControllerActionHandler(Action module, ItemRegistry itemRegistry, EventPublisher eventPublisher) {
|
||||
super(module);
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Map<String, Object> execute(Map<String, Object> context) {
|
||||
Stream.of(OUTPUT, P_INSPECTOR, I_INSPECTOR, D_INSPECTOR, E_INSPECTOR).forEach(arg -> {
|
||||
final String itemName = (String) module.getConfiguration().get(arg);
|
||||
|
||||
if (itemName == null || itemName.isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BigDecimal command = (BigDecimal) context.get("1." + arg);
|
||||
|
||||
if (command != null) {
|
||||
final DecimalType outputValue = new DecimalType(command);
|
||||
final ItemCommandEvent itemCommandEvent = ItemEventFactory.createCommandEvent(itemName, outputValue);
|
||||
|
||||
eventPublisher.post(itemCommandEvent);
|
||||
} else {
|
||||
logger.warn(
|
||||
"Command was not posted because either the configuration was not correct or a service was missing: ItemName: {}, Command: {}, eventPublisher: {}, ItemRegistry: {}",
|
||||
itemName, command, eventPublisher, itemRegistry);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.handler;
|
||||
|
||||
import static org.openhab.automation.pidcontroller.internal.PIDControllerConstants.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.automation.pidcontroller.internal.PIDException;
|
||||
import org.openhab.core.automation.ModuleHandlerCallback;
|
||||
import org.openhab.core.automation.Trigger;
|
||||
import org.openhab.core.automation.handler.BaseTriggerModuleHandler;
|
||||
import org.openhab.core.automation.handler.TriggerHandlerCallback;
|
||||
import org.openhab.core.common.NamedThreadFactory;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventFilter;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.events.EventSubscriber;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemNotFoundException;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.items.events.ItemEventFactory;
|
||||
import org.openhab.core.items.events.ItemStateChangedEvent;
|
||||
import org.openhab.core.items.events.ItemStateEvent;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
* @author Fabian Wolter - Add PID debug output values
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerTriggerHandler extends BaseTriggerModuleHandler implements EventSubscriber {
|
||||
public static final String MODULE_TYPE_ID = AUTOMATION_NAME + ".trigger";
|
||||
private static final Set<String> SUBSCRIBED_EVENT_TYPES = Set.of(ItemStateEvent.TYPE, ItemStateChangedEvent.TYPE);
|
||||
private final Logger logger = LoggerFactory.getLogger(PIDControllerTriggerHandler.class);
|
||||
private final ScheduledExecutorService scheduler = Executors
|
||||
.newSingleThreadScheduledExecutor(new NamedThreadFactory("OH-automation-" + AUTOMATION_NAME, true));
|
||||
private final ServiceRegistration<?> eventSubscriberRegistration;
|
||||
private final PIDController controller;
|
||||
private final int loopTimeMs;
|
||||
private @Nullable ScheduledFuture<?> controllerjob;
|
||||
private long previousTimeMs = System.currentTimeMillis();
|
||||
private Item inputItem;
|
||||
private Item setpointItem;
|
||||
private EventFilter eventFilter;
|
||||
|
||||
public PIDControllerTriggerHandler(Trigger module, ItemRegistry itemRegistry, EventPublisher eventPublisher,
|
||||
BundleContext bundleContext) {
|
||||
super(module);
|
||||
|
||||
Configuration config = module.getConfiguration();
|
||||
|
||||
String inputItemName = (String) requireNonNull(config.get(CONFIG_INPUT_ITEM), "Input item is not set");
|
||||
String setpointItemName = (String) requireNonNull(config.get(CONFIG_SETPOINT_ITEM), "Setpoint item is not set");
|
||||
|
||||
try {
|
||||
inputItem = itemRegistry.getItem(inputItemName);
|
||||
} catch (ItemNotFoundException e) {
|
||||
throw new IllegalArgumentException("Configured input item not found: " + inputItemName, e);
|
||||
}
|
||||
|
||||
try {
|
||||
setpointItem = itemRegistry.getItem(setpointItemName);
|
||||
} catch (ItemNotFoundException e) {
|
||||
throw new IllegalArgumentException("Configured setpoint item not found: " + setpointItemName, e);
|
||||
}
|
||||
|
||||
double outputLowerLimit = getDoubleFromConfig(config, CONFIG_OUTPUT_LOWER_LIMIT);
|
||||
double outputUpperLimit = getDoubleFromConfig(config, CONFIG_OUTPUT_UPPER_LIMIT);
|
||||
double kpAdjuster = getDoubleFromConfig(config, CONFIG_KP_GAIN);
|
||||
double kiAdjuster = getDoubleFromConfig(config, CONFIG_KI_GAIN);
|
||||
double kdAdjuster = getDoubleFromConfig(config, CONFIG_KD_GAIN);
|
||||
double kdTimeConstant = getDoubleFromConfig(config, CONFIG_KD_TIMECONSTANT);
|
||||
|
||||
loopTimeMs = ((BigDecimal) requireNonNull(config.get(CONFIG_LOOP_TIME), CONFIG_LOOP_TIME + " is not set"))
|
||||
.intValue();
|
||||
|
||||
controller = new PIDController(outputLowerLimit, outputUpperLimit, kpAdjuster, kiAdjuster, kdAdjuster,
|
||||
kdTimeConstant);
|
||||
|
||||
eventFilter = event -> {
|
||||
String topic = event.getTopic();
|
||||
|
||||
return topic.equals("openhab/items/" + inputItemName + "/state")
|
||||
|| topic.equals("openhab/items/" + inputItemName + "/statechanged")
|
||||
|| topic.equals("openhab/items/" + setpointItemName + "/statechanged");
|
||||
};
|
||||
|
||||
eventSubscriberRegistration = bundleContext.registerService(EventSubscriber.class.getName(), this, null);
|
||||
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent(inputItemName, RefreshType.REFRESH));
|
||||
|
||||
controllerjob = scheduler.scheduleWithFixedDelay(this::calculate, 0, loopTimeMs, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private <T> T requireNonNull(T obj, String message) {
|
||||
if (obj == null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
private double getDoubleFromConfig(Configuration config, String key) {
|
||||
return ((BigDecimal) Objects.requireNonNull(config.get(key), key + " is not set")).doubleValue();
|
||||
}
|
||||
|
||||
private void calculate() {
|
||||
double input;
|
||||
double setpoint;
|
||||
|
||||
try {
|
||||
input = getItemValueAsNumber(inputItem);
|
||||
} catch (PIDException e) {
|
||||
logger.warn("Input item: {}", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setpoint = getItemValueAsNumber(setpointItem);
|
||||
} catch (PIDException e) {
|
||||
logger.warn("Setpoint item: {}", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
PIDOutputDTO output = controller.calculate(input, setpoint, now - previousTimeMs);
|
||||
previousTimeMs = now;
|
||||
|
||||
Map<String, BigDecimal> outputs = new HashMap<>();
|
||||
|
||||
putBigDecimal(outputs, OUTPUT, output.getOutput());
|
||||
putBigDecimal(outputs, P_INSPECTOR, output.getProportionalPart());
|
||||
putBigDecimal(outputs, I_INSPECTOR, output.getIntegralPart());
|
||||
putBigDecimal(outputs, D_INSPECTOR, output.getDerivativePart());
|
||||
putBigDecimal(outputs, E_INSPECTOR, output.getError());
|
||||
|
||||
ModuleHandlerCallback localCallback = callback;
|
||||
if (localCallback != null && localCallback instanceof TriggerHandlerCallback) {
|
||||
((TriggerHandlerCallback) localCallback).triggered(module, outputs);
|
||||
} else {
|
||||
logger.warn("No callback set");
|
||||
}
|
||||
}
|
||||
|
||||
private void putBigDecimal(Map<String, BigDecimal> map, String key, double value) {
|
||||
map.put(key, BigDecimal.valueOf(value));
|
||||
}
|
||||
|
||||
private double getItemValueAsNumber(Item item) throws PIDException {
|
||||
State setpointState = item.getState();
|
||||
|
||||
if (setpointState instanceof Number) {
|
||||
double doubleValue = ((Number) setpointState).doubleValue();
|
||||
|
||||
if (Double.isFinite(doubleValue)) {
|
||||
return doubleValue;
|
||||
}
|
||||
} else if (setpointState instanceof StringType) {
|
||||
try {
|
||||
return Double.parseDouble(setpointState.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
throw new PIDException(
|
||||
"Item type is not a number: " + setpointState.getClass().getSimpleName() + ": " + setpointState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Event event) {
|
||||
if (event instanceof ItemStateChangedEvent) {
|
||||
calculate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSubscribedEventTypes() {
|
||||
return SUBSCRIBED_EVENT_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return eventFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
eventSubscriberRegistration.unregister();
|
||||
|
||||
ScheduledFuture<?> localControllerjob = controllerjob;
|
||||
if (localControllerjob != null) {
|
||||
localControllerjob.cancel(true);
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.handler;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabian Wolter - Initial Contribution
|
||||
*/
|
||||
public class PIDOutputDTO {
|
||||
private double output;
|
||||
private double proportionalPart;
|
||||
private double integralPart;
|
||||
private double derivativePart;
|
||||
private double error;
|
||||
|
||||
public PIDOutputDTO(double output, double proportionalPart, double integralPart, double derivativePart,
|
||||
double error) {
|
||||
this.output = output;
|
||||
this.proportionalPart = proportionalPart;
|
||||
this.integralPart = integralPart;
|
||||
this.derivativePart = derivativePart;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public double getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public double getProportionalPart() {
|
||||
return proportionalPart;
|
||||
}
|
||||
|
||||
public double getIntegralPart() {
|
||||
return integralPart;
|
||||
}
|
||||
|
||||
public double getDerivativePart() {
|
||||
return derivativePart;
|
||||
}
|
||||
|
||||
public double getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.template;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.automation.pidcontroller.internal.PIDControllerConstants;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerActionHandler;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerTriggerHandler;
|
||||
import org.openhab.automation.pidcontroller.internal.type.PIDControllerActionType;
|
||||
import org.openhab.core.automation.Action;
|
||||
import org.openhab.core.automation.Condition;
|
||||
import org.openhab.core.automation.Trigger;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.automation.template.RuleTemplate;
|
||||
import org.openhab.core.automation.util.ModuleBuilder;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerRuleTemplate extends RuleTemplate {
|
||||
public static final String UID = "PIDControllerRuleTemplate";
|
||||
|
||||
public static PIDControllerRuleTemplate initialize() {
|
||||
final String triggerId = UUID.randomUUID().toString();
|
||||
|
||||
final List<Trigger> triggers = List.of(ModuleBuilder.createTrigger().withId(triggerId)
|
||||
.withTypeUID(PIDControllerTriggerHandler.MODULE_TYPE_ID).withLabel("PID Controller Trigger").build());
|
||||
|
||||
final Map<String, String> actionInputs = Map.of(PIDControllerActionType.INPUT,
|
||||
triggerId + "." + PIDControllerConstants.OUTPUT);
|
||||
|
||||
final List<Action> actions = List.of(ModuleBuilder.createAction().withId(UUID.randomUUID().toString())
|
||||
.withTypeUID(PIDControllerActionHandler.MODULE_TYPE_ID).withLabel("PID Controller Action")
|
||||
.withInputs(actionInputs).build());
|
||||
|
||||
return new PIDControllerRuleTemplate(Set.of("PID Controller"), triggers, Collections.emptyList(), actions,
|
||||
Collections.emptyList());
|
||||
}
|
||||
|
||||
public PIDControllerRuleTemplate(Set<String> tags, List<Trigger> triggers, List<Condition> conditions,
|
||||
List<Action> actions, List<ConfigDescriptionParameter> configDescriptions) {
|
||||
super(UID, "PID Controller", "Template for a PID controlled rule", tags, triggers, conditions, actions,
|
||||
configDescriptions, Visibility.VISIBLE);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.template;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.template.RuleTemplate;
|
||||
import org.openhab.core.automation.template.RuleTemplateProvider;
|
||||
import org.openhab.core.common.registry.ProviderChangeListener;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@Component
|
||||
@NonNullByDefault
|
||||
public class PIDControllerTemplateProvider implements RuleTemplateProvider {
|
||||
private static final RuleTemplate PROVIDED_RULE_TEMPLATE = PIDControllerRuleTemplate.initialize();
|
||||
|
||||
@Override
|
||||
public @Nullable RuleTemplate getTemplate(String uid, @Nullable Locale locale) {
|
||||
return uid.equals(PIDControllerRuleTemplate.UID) ? PROVIDED_RULE_TEMPLATE : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<RuleTemplate> getTemplates(@Nullable Locale locale) {
|
||||
return Set.of(PROVIDED_RULE_TEMPLATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProviderChangeListener(ProviderChangeListener<RuleTemplate> listener) {
|
||||
// does nothing because this provider does not change
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<RuleTemplate> getAll() {
|
||||
return Set.of(PROVIDED_RULE_TEMPLATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProviderChangeListener(ProviderChangeListener<RuleTemplate> listener) {
|
||||
// does nothing because this provider does not change
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.type;
|
||||
|
||||
import static org.openhab.automation.pidcontroller.internal.PIDControllerConstants.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerActionHandler;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.automation.type.ActionType;
|
||||
import org.openhab.core.automation.type.Input;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameter.Type;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameterBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerActionType extends ActionType {
|
||||
public static final String INPUT = "input";
|
||||
|
||||
public static PIDControllerActionType initialize() {
|
||||
final ConfigDescriptionParameter outputItem = ConfigDescriptionParameterBuilder.create(OUTPUT, Type.TEXT)
|
||||
.withRequired(true).withMultiple(false).withContext("item").withLabel("Output Item")
|
||||
.withDescription("Item to send output").build();
|
||||
final ConfigDescriptionParameter pInspectorItem = ConfigDescriptionParameterBuilder
|
||||
.create(P_INSPECTOR, Type.TEXT).withRequired(false).withMultiple(false).withContext("item")
|
||||
.withLabel("P Inspector Item").withDescription("Item for debugging the P part").build();
|
||||
final ConfigDescriptionParameter iInspectorItem = ConfigDescriptionParameterBuilder
|
||||
.create(I_INSPECTOR, Type.TEXT).withRequired(false).withMultiple(false).withContext("item")
|
||||
.withLabel("I Inspector Item").withDescription("Item for debugging the I part").build();
|
||||
final ConfigDescriptionParameter dInspectorItem = ConfigDescriptionParameterBuilder
|
||||
.create(D_INSPECTOR, Type.TEXT).withRequired(false).withMultiple(false).withContext("item")
|
||||
.withLabel("D Inspector Item").withDescription("Item for debugging the D part").build();
|
||||
final ConfigDescriptionParameter eInspectorItem = ConfigDescriptionParameterBuilder
|
||||
.create(E_INSPECTOR, Type.TEXT).withRequired(false).withMultiple(false).withContext("item")
|
||||
.withLabel("Error Inspector Item").withDescription("Item for debugging the error value").build();
|
||||
|
||||
List<ConfigDescriptionParameter> config = List.of(outputItem, pInspectorItem, iInspectorItem, dInspectorItem,
|
||||
eInspectorItem);
|
||||
|
||||
List<Input> inputs = List.of(createInput(INPUT), createInput(P_INSPECTOR), createInput(I_INSPECTOR),
|
||||
createInput(D_INSPECTOR), createInput(E_INSPECTOR));
|
||||
|
||||
return new PIDControllerActionType(config, inputs);
|
||||
}
|
||||
|
||||
private static Input createInput(String name) {
|
||||
return new Input(name, BigDecimal.class.getName());
|
||||
}
|
||||
|
||||
public PIDControllerActionType(List<ConfigDescriptionParameter> configDescriptions, List<Input> inputs) {
|
||||
super(PIDControllerActionHandler.MODULE_TYPE_ID, configDescriptions, "calculate PID output", null, null,
|
||||
Visibility.VISIBLE, inputs, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.type;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerActionHandler;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerTriggerHandler;
|
||||
import org.openhab.core.automation.type.ModuleType;
|
||||
import org.openhab.core.automation.type.ModuleTypeProvider;
|
||||
import org.openhab.core.common.registry.ProviderChangeListener;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@Component
|
||||
@NonNullByDefault
|
||||
public class PIDControllerModuleTypeProvider implements ModuleTypeProvider {
|
||||
private static final Map<String, ModuleType> PROVIDED_MODULE_TYPES = Map.of(
|
||||
PIDControllerActionHandler.MODULE_TYPE_ID, PIDControllerActionType.initialize(),
|
||||
PIDControllerTriggerHandler.MODULE_TYPE_ID, PIDControllerTriggerType.initialize());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends ModuleType> T getModuleType(@Nullable String UID, @Nullable Locale locale) {
|
||||
return (T) PROVIDED_MODULE_TYPES.get(UID);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends ModuleType> Collection<T> getModuleTypes(@Nullable Locale locale) {
|
||||
return (Collection<T>) PROVIDED_MODULE_TYPES.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProviderChangeListener(ProviderChangeListener<ModuleType> listener) {
|
||||
// does nothing because this provider does not change
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ModuleType> getAll() {
|
||||
return Collections.unmodifiableCollection(PROVIDED_MODULE_TYPES.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProviderChangeListener(ProviderChangeListener<ModuleType> listener) {
|
||||
// does nothing because this provider does not change
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal.type;
|
||||
|
||||
import static org.openhab.automation.pidcontroller.internal.PIDControllerConstants.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.automation.pidcontroller.internal.handler.PIDControllerTriggerHandler;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.automation.type.Output;
|
||||
import org.openhab.core.automation.type.TriggerType;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameter.Type;
|
||||
import org.openhab.core.config.core.ConfigDescriptionParameterBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Hilbrand Bouwkamp - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PIDControllerTriggerType extends TriggerType {
|
||||
private static final String DEFAULT_LOOPTIME_MS = "1000";
|
||||
|
||||
public static PIDControllerTriggerType initialize() {
|
||||
List<ConfigDescriptionParameter> configDescriptions = new ArrayList<>();
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_INPUT_ITEM, Type.TEXT).withRequired(true)
|
||||
.withReadOnly(true).withMultiple(false).withContext("item").withLabel("Input Item")
|
||||
.withDescription("Item to monitor").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_SETPOINT_ITEM, Type.TEXT)
|
||||
.withRequired(true).withReadOnly(true).withMultiple(false).withContext("item").withLabel("Setpoint")
|
||||
.withDescription("Targeted setpoint").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KP_GAIN, Type.DECIMAL).withRequired(true)
|
||||
.withMultiple(false).withDefault("1.0").withLabel("Proportional Gain (Kp)")
|
||||
.withDescription("Change to output propertional to current error value.").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KI_GAIN, Type.DECIMAL).withRequired(true)
|
||||
.withMultiple(false).withDefault("1.0").withLabel("Integral Gain (Ki)")
|
||||
.withDescription("Accelerate movement towards the setpoint.").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KD_GAIN, Type.DECIMAL).withRequired(true)
|
||||
.withMultiple(false).withDefault("1.0").withLabel("Derivative Gain (Kd)")
|
||||
.withDescription("Slows the rate of change of the output.").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KD_TIMECONSTANT, Type.DECIMAL)
|
||||
.withRequired(true).withMultiple(false).withDefault("1.0").withLabel("Derivative Time Constant")
|
||||
.withDescription("Slows the rate of change of the D Part (T1) in seconds.").withUnit("s").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_OUTPUT_LOWER_LIMIT, Type.DECIMAL)
|
||||
.withRequired(true).withMultiple(false).withDefault("0").withLabel("Output Lower Limit")
|
||||
.withDescription("The output of the PID controller will be min this value").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_OUTPUT_UPPER_LIMIT, Type.DECIMAL)
|
||||
.withRequired(true).withMultiple(false).withDefault("100").withLabel("Output Upper Limit")
|
||||
.withDescription("The output of the PID controller will be max this value").build());
|
||||
configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_LOOP_TIME, Type.DECIMAL)
|
||||
.withRequired(true).withMultiple(false).withDefault(DEFAULT_LOOPTIME_MS).withLabel("Loop Time")
|
||||
.withDescription("The interval the output value is updated in ms").withUnit("ms").build());
|
||||
|
||||
Output output = new Output(OUTPUT, BigDecimal.class.getName(), "Output", "Output value of the PID Controller",
|
||||
null, null, null);
|
||||
Output pInspector = new Output(P_INSPECTOR, BigDecimal.class.getName(), "P Inspector",
|
||||
"Current P value of the pid controller", null, null, null);
|
||||
Output iInspector = new Output(I_INSPECTOR, BigDecimal.class.getName(), "I Inspector",
|
||||
"Current I value of the pid controller", null, null, null);
|
||||
Output dInspector = new Output(D_INSPECTOR, BigDecimal.class.getName(), "D Inspector",
|
||||
"Current D value of the pid controller", null, null, null);
|
||||
Output eInspector = new Output(E_INSPECTOR, BigDecimal.class.getName(), "Error Value Inspector",
|
||||
"Current error value of the pid controller", null, null, null);
|
||||
|
||||
List<Output> outputs = List.of(output, pInspector, iInspector, dInspector, eInspector);
|
||||
|
||||
return new PIDControllerTriggerType(configDescriptions, outputs);
|
||||
}
|
||||
|
||||
public PIDControllerTriggerType(List<ConfigDescriptionParameter> configDescriptions, List<Output> outputs) {
|
||||
super(PIDControllerTriggerHandler.MODULE_TYPE_ID, configDescriptions, "PID controller triggers", null, null,
|
||||
Visibility.VISIBLE, outputs);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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.automation.pidcontroller.internal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test for LowpassFilter.
|
||||
*
|
||||
* @author Fabian Wolter - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class LowpassFilterTest {
|
||||
@Test
|
||||
void test0to1after1tau() {
|
||||
double output = LowpassFilter.calculate(0, 1, 1);
|
||||
assertEquals(0.63, output, 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test0to1after2tau() {
|
||||
double output = LowpassFilter.calculate(0, 1, 1);
|
||||
output = LowpassFilter.calculate(output, 1, 1);
|
||||
assertEquals(0.86, output, 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test0to1after5tau() {
|
||||
double output = LowpassFilter.calculate(0, 1, 1);
|
||||
output = LowpassFilter.calculate(output, 1, 1);
|
||||
output = LowpassFilter.calculate(output, 1, 1);
|
||||
output = LowpassFilter.calculate(output, 1, 1);
|
||||
output = LowpassFilter.calculate(output, 1, 1);
|
||||
assertEquals(0.99, output, 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test0to1after1tau2timeConstant() {
|
||||
double output = LowpassFilter.calculate(0, 1, 2);
|
||||
assertEquals(0.86, output, 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test0to1after0_1tau() {
|
||||
double output = LowpassFilter.calculate(0, 1, 0.1);
|
||||
assertEquals(0.095162582, output, 0.000000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test1to0after1tau() {
|
||||
double output = LowpassFilter.calculate(1, 0, 1);
|
||||
assertEquals(0.36, output, 0.01);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user