Hi,

I have used OpenHAB for a while for simpler tasks. I would now like to implement a PID regulator as a rule. I have used the ivPID (https://github.com/ivmech/ivPID) as a starting point.

The problem is that I cannot get “global” variables to work. I understood from the documentation and from other forum posts that variables can be defined as global (where the global scope is the rule file) if they are declared outside of the rules. Some variables work from some rules, but not from all and I do not understand why. I know I could use items to store the calculations, but as I do not (at this point) intend to use them for anything I prefer to keep them hidden from event logs etc. by defining them as variables.

Please note the code is not complete, I have only added few functions to start off at some point.

Rule file:

import javax.measure.quantity

// PID regulator

// MF2020 - Based on ivPID Python code

val Kp = 0.07 as Number

val Ki = 0.0007 as Number

val Kd = 0 as Number

var sample_time = 0.0 as Number

var current_time = (now.getMillis() as Number)

var last_time = (now.getMillis() as Number)

var PTerm = (0.0 as Number).doubleValue

var ITerm = (0.0 as Number).doubleValue

var DTerm = (0.0 as Number).doubleValue

var last_error = 0.0 as Number

var error = 0.0 as Number

var windup_guard = 0.0 as Number

var output = (0.0 as Number).doubleValue

var max_output = 20 as Number

var min_output = 0 as Number

```
// Trigger updates
rule "shuntti_pid_update_trig" when Item pannu_paluuvesi received update then
if (shuntti_pid_active.state == ON) {
shuntti_pid_update.sendCommand((pannu_paluuvesi.state as QuantityType<Number>).doubleValue)
}
end
// Clear PID calculations
rule "shuntti_pid_clear_f" when Item shuntti_pid_active changed then
logInfo("Shuntti_PID", "Cleared calculations")
PTerm = (0.0 as Number).doubleValue
ITerm = (0.0 as Number).doubleValue
DTerm = (0.0 as Number).doubleValue
last_error = 0.0 as Number
error = 0.0 as Number
windup_guard = 0.0 as Number
output = 0.0 as Number
```

end

// Update PID calculation

rule “shuntti_pid_update_f” when Item shuntti_pid_update received command then

logInfo(“Shuntti_PID”, “Starting”)

error = ((shuntti_pid_setpoint.state as Number) - (shuntti_pid_update.state as Number))

current_time = now().getMillis() as Number

var delta_time = (current_time-last_time) as Number

var delta_error = (error - last_error) as Number

```
if (delta_time >= sample_time){
PTerm = Kp * error
ITerm = ITerm + (error * delta_time)
if (ITerm < -windup_guard) {
ITerm = -windup_guard
}
else if (ITerm > windup_guard) {
ITerm = windup_guard
}
if (delta_time > 0) {
logInfo("Shuntti_PID", "C1")
var Dtermc = delta_error / delta_time
logInfo("Shuntti_PID", Dtermc.toString())
Dterm = Dtermc
}
last_time = current_time
last_error = error
logInfo("Shuntti_PID", "A")
output = PTerm + (Ki * ITerm) + (Kd * Dterm)
// var x_output = Pterm
logInfo("Shuntti_PID", Pterm.toString())
logInfo("Shuntti_PID", Ki.toString())
logInfo("Shuntti_PID", ITerm.toString())
output = PTerm + (Ki * ITerm)
logInfo("Shuntti_PID", "G")
if (output < min_output) {
output = min_output
logInfo("Shuntti_PID", "H")
} else if (output > max_output) {
output = max_output
logInfo("Shuntti_PID", "I")
}
shuntti_pid_output.sendCommand(output)
logInfo("Shuntti_PID", "D")
}
end
```

To test the rule, I have activated (sent cmd ON) to *shuntti_pid_activate* (to run *shuntti_pid_clear_f*) and waited for the temperature *pannu_panuuvesi* to update.

Log:

2020-05-05 14:56:47.348 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model ‘shuntti_pid.rules’

2020-05-05 14:56:53.626 [INFO ] [e.smarthome.model.script.Shuntti_PID] - Cleared calculations

2020-05-05 14:57:58.789 [INFO ] [e.smarthome.model.script.Shuntti_PID] - Starting

2020-05-05 14:57:58.817 [INFO ] [e.smarthome.model.script.Shuntti_PID] - C1

2020-05-05 14:57:58.823 [INFO ] [e.smarthome.model.script.Shuntti_PID] - 0.00010255

2020-05-05 14:57:58.825 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘shuntti_pid_update_f’: An error occurred during the script execution: Couldn’t invoke ‘assignValueTo’ for feature JvmVoid: (eProxyURI: shuntti_pid.rules#|::0.2.2.2.0.5.1.0.3.1.0.3::0::/1)

What confuses me is that writing to some of the variables seem to work, but not to all. I have added some logInfo lines to show more clearly where the rule aborts (when setting Dterm = dTermc).

I think my variable declarations are overkill, but I tried to make them more specific to fix it, however without success. If I understand it correctly, based on missing errors, the *shuntti_pid_clear_f* can write to Dterm, but not *shuntti_pid_update_f*.

Thankful for any advice!

Items defined as follows, however I don’t know if relevant:

Number shuntti_pid_setpoint

Switch shuntti_pid_active

Number shuntti_pid_output

Number shuntti_pid_update

Switch shuntti_pid_clear

When starting, *shuntti_pid_active* is OFF, but changed to ON. *shuntti_pid_setpoint* is set to a numeric value (25).

- Platform information:
- Hardware: Raspberry Pi 3B+
- OS: Raspbian + OpenHAB docker image
- Java Runtime Environment: Standard from OpenHAB Docker image
- openHAB version: 2.5