2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.automation.pidcontroller.internal.type;
15 import static org.openhab.automation.pidcontroller.internal.PIDControllerConstants.*;
17 import java.math.BigDecimal;
18 import java.util.ArrayList;
19 import java.util.List;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.automation.pidcontroller.internal.handler.PIDControllerTriggerHandler;
24 import org.openhab.core.automation.Visibility;
25 import org.openhab.core.automation.type.Output;
26 import org.openhab.core.automation.type.TriggerType;
27 import org.openhab.core.config.core.ConfigDescriptionParameter;
28 import org.openhab.core.config.core.ConfigDescriptionParameter.Type;
29 import org.openhab.core.config.core.ConfigDescriptionParameterBuilder;
33 * @author Hilbrand Bouwkamp - Initial Contribution
34 * @author Fabian Wolter - Add inspector Items for debugging
37 public class PIDControllerTriggerType extends TriggerType {
38 private static final String DEFAULT_LOOPTIME_MS = "1000";
39 private static final String ITEM = "item";
41 public static PIDControllerTriggerType initialize() {
42 List<ConfigDescriptionParameter> configDescriptions = new ArrayList<>();
43 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_INPUT_ITEM, Type.TEXT) //
44 .withRequired(true) //
45 .withMultiple(false) //
47 .withLabel("Input Item") //
48 .withDescription("Item to monitor") //
50 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_SETPOINT_ITEM, Type.TEXT) //
51 .withRequired(true) //
52 .withMultiple(false) //
54 .withLabel("Setpoint") //
55 .withDescription("Targeted setpoint") //
57 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KP_GAIN, Type.DECIMAL).withRequired(true) //
58 .withMultiple(false) //
59 .withDefault("1.0") //
60 .withMinimum(BigDecimal.ZERO) //
61 .withLabel("Proportional Gain (Kp)") //
62 .withDescription("Change to output propertional to current error value.") //
64 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KI_GAIN, Type.DECIMAL) //
65 .withRequired(true) //
66 .withMultiple(false) //
67 .withDefault("1.0") //
68 .withMinimum(BigDecimal.ZERO) //
69 .withLabel("Integral Gain (Ki)") //
70 .withDescription("Accelerate movement towards the setpoint.") //
72 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KD_GAIN, Type.DECIMAL) //
73 .withRequired(true) //
74 .withMultiple(false) //
75 .withDefault("1.0") //
76 .withMinimum(BigDecimal.ZERO) //
77 .withLabel("Derivative Gain (Kd)") //
78 .withDescription("Slows the rate of change of the output.") //
80 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_KD_TIMECONSTANT, Type.DECIMAL) //
81 .withRequired(true) //
82 .withMultiple(false) //
83 .withMinimum(BigDecimal.ZERO) //
84 .withDefault("1.0") //
85 .withLabel("Derivative Time Constant") //
86 .withDescription("Slows the rate of change of the D-part (T1) in seconds.") //
89 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_LOOP_TIME, Type.DECIMAL) //
90 .withRequired(true) //
91 .withMultiple(false) //
92 .withDefault(DEFAULT_LOOPTIME_MS) //
93 .withLabel("Loop Time") //
94 .withDescription("The interval the output value is updated in ms") //
97 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_I_MIN, Type.DECIMAL) //
98 .withRequired(false) //
99 .withMultiple(false) //
100 .withLabel("I-part Lower Limit") //
101 .withDescription("The I-part will be min this value. Can be left empty for no limit.") //
103 configDescriptions.add(ConfigDescriptionParameterBuilder.create(CONFIG_I_MAX, Type.DECIMAL) //
104 .withRequired(false) //
105 .withMultiple(false) //
106 .withLabel("I-part Upper Limit") //
107 .withDescription("The I-part will be max this value. Can be left empty for no limit.") //
109 configDescriptions.add(ConfigDescriptionParameterBuilder.create(P_INSPECTOR, Type.TEXT) //
110 .withRequired(false) //
111 .withMultiple(false) //
112 .withContext(ITEM) //
113 .withLabel("P Inspector Item") //
114 .withDescription("Item for debugging the P part") //
116 configDescriptions.add(ConfigDescriptionParameterBuilder.create(I_INSPECTOR, Type.TEXT) //
117 .withRequired(false) //
118 .withMultiple(false) //
119 .withContext(ITEM) //
120 .withLabel("I Inspector Item") //
121 .withDescription("Item for debugging the I part") //
123 configDescriptions.add(ConfigDescriptionParameterBuilder.create(D_INSPECTOR, Type.TEXT) //
124 .withRequired(false).withMultiple(false) //
125 .withContext(ITEM) //
126 .withLabel("D Inspector Item") //
127 .withDescription("Item for debugging the D part") //
129 configDescriptions.add(ConfigDescriptionParameterBuilder.create(E_INSPECTOR, Type.TEXT) //
130 .withRequired(false).withMultiple(false) //
131 .withContext(ITEM) //
132 .withLabel("Error Inspector Item") //
133 .withDescription("Item for debugging the error value") //
136 Output output = new Output(COMMAND, BigDecimal.class.getName(), "Output", "Output value of the PID Controller",
137 Set.of("command"), null, null);
139 return new PIDControllerTriggerType(configDescriptions, List.of(output));
142 public PIDControllerTriggerType(List<ConfigDescriptionParameter> configDescriptions, List<Output> outputs) {
143 super(PIDControllerTriggerHandler.MODULE_TYPE_ID, configDescriptions, "PID controller triggers", null, null,
144 Visibility.VISIBLE, outputs);