hoffmation-base 1.0.55 → 1.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/liquid-pid.d.ts +42 -0
- package/lib/liquid-pid.js +97 -0
- package/lib/models/deviceSettings/heaterSettings.d.ts +1 -0
- package/lib/models/deviceSettings/heaterSettings.js +1 -0
- package/lib/server/devices/hmIPDevices/hmIpDevice.d.ts +1 -1
- package/lib/server/devices/hmIPDevices/hmIpDevice.js +1 -1
- package/lib/server/devices/zigbee/BaseDevices/zigbeeDevice.d.ts +1 -1
- package/lib/server/devices/zigbee/BaseDevices/zigbeeDevice.js +1 -1
- package/lib/server/devices/zigbee/BaseDevices/zigbeeHeater.d.ts +3 -0
- package/lib/server/devices/zigbee/BaseDevices/zigbeeHeater.js +20 -0
- package/lib/server/devices/zigbee/zigbeeBlitzShp.d.ts +2 -5
- package/lib/server/devices/zigbee/zigbeeBlitzShp.js +4 -24
- package/lib/server/devices/zigbee/zigbeeEuroHeater.d.ts +4 -0
- package/lib/server/devices/zigbee/zigbeeEuroHeater.js +36 -6
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* !!Ported from liquid pid!!!!
|
|
3
|
+
* Control the PWM relays from the temperature
|
|
4
|
+
*
|
|
5
|
+
* I'm a NodeJS guy not a scientist, so please be a careful!!!
|
|
6
|
+
* FYI: http://en.wikipedia.org/wiki/PID_controller
|
|
7
|
+
*
|
|
8
|
+
* @module controller
|
|
9
|
+
*
|
|
10
|
+
* @author https://github.com/hekike/liquid-pid
|
|
11
|
+
* @licence MIT
|
|
12
|
+
**/
|
|
13
|
+
export declare class PIDController {
|
|
14
|
+
private _Tref;
|
|
15
|
+
private readonly _Pmax;
|
|
16
|
+
private _Kp;
|
|
17
|
+
private _Ki;
|
|
18
|
+
private _Kd;
|
|
19
|
+
private _P;
|
|
20
|
+
private _I;
|
|
21
|
+
private _D;
|
|
22
|
+
private readonly _MaxP;
|
|
23
|
+
private readonly _MaxI;
|
|
24
|
+
private readonly _MaxD;
|
|
25
|
+
private readonly _MaxU;
|
|
26
|
+
private _e;
|
|
27
|
+
private _U;
|
|
28
|
+
constructor(options: PIDOptions);
|
|
29
|
+
tune(Kp: number, Ki: number, Kd: number): void;
|
|
30
|
+
getRefTemperature(): number;
|
|
31
|
+
setPoint(temp: number): number;
|
|
32
|
+
calculate(actualTemperature: number): number;
|
|
33
|
+
}
|
|
34
|
+
export interface PIDOptions {
|
|
35
|
+
Kp?: number;
|
|
36
|
+
Ki?: number;
|
|
37
|
+
Kd?: number;
|
|
38
|
+
Pmax?: number;
|
|
39
|
+
temp?: {
|
|
40
|
+
ref: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PIDController = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* !!Ported from liquid pid!!!!
|
|
6
|
+
* Control the PWM relays from the temperature
|
|
7
|
+
*
|
|
8
|
+
* I'm a NodeJS guy not a scientist, so please be a careful!!!
|
|
9
|
+
* FYI: http://en.wikipedia.org/wiki/PID_controller
|
|
10
|
+
*
|
|
11
|
+
* @module controller
|
|
12
|
+
*
|
|
13
|
+
* @author https://github.com/hekike/liquid-pid
|
|
14
|
+
* @licence MIT
|
|
15
|
+
**/
|
|
16
|
+
class PIDController {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
var _a, _b, _c, _d, _f, _g;
|
|
19
|
+
this._U = null;
|
|
20
|
+
this._Tref = (_b = (_a = options.temp) === null || _a === void 0 ? void 0 : _a.ref) !== null && _b !== void 0 ? _b : 0; // Point temperature (This is the temp what you want to reach and hold) (°C)
|
|
21
|
+
this._Pmax = (_c = options.Pmax) !== null && _c !== void 0 ? _c : 4000; // Max Power, this is the maximum output of your heater (W) (Yep, this is the output what you want)
|
|
22
|
+
// Params of the PID controller
|
|
23
|
+
this._Kp = (_d = options.Kp) !== null && _d !== void 0 ? _d : 25; // Proportional gain, a tuning parameter
|
|
24
|
+
this._Ki = (_f = options.Ki) !== null && _f !== void 0 ? _f : 1000; // Integral gain, a tuning parameter
|
|
25
|
+
this._Kd = (_g = options.Kd) !== null && _g !== void 0 ? _g : 9; // Derivative gain, a tuning parameter
|
|
26
|
+
this._P = 0; // Proportional value ("reduces a large part of the overall error")
|
|
27
|
+
this._I = 0; // Integral value ("reduces the final error in a system")
|
|
28
|
+
this._D = 0; // Derivative value ("helps reduce overshoot and ringing", "~speed")
|
|
29
|
+
this._MaxP = 1000; // Limit the maximum value of the abs Proportional (because micro controller registers)
|
|
30
|
+
this._MaxI = 1000; // Limit the maximum value of the abs Integral (because micro controller registers)
|
|
31
|
+
this._MaxD = 1000; // Limit the maximum value of the abs Derivative (because micro controller registers)
|
|
32
|
+
this._MaxU = 1000; // Limit the maximum value of the controller output (it's not equal with our P "output")
|
|
33
|
+
// Other variables
|
|
34
|
+
this._e = 0; // Actual error
|
|
35
|
+
this._U = null; // Controller output (it's not equal with our P "output")
|
|
36
|
+
}
|
|
37
|
+
tune(Kp, Ki, Kd) {
|
|
38
|
+
if (!isNaN(Kp) || !isNaN(Ki) || !isNaN(Kd)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this._Kp = Kp;
|
|
42
|
+
this._Ki = Ki;
|
|
43
|
+
this._Kd = Kd;
|
|
44
|
+
}
|
|
45
|
+
getRefTemperature() {
|
|
46
|
+
return this._Tref;
|
|
47
|
+
}
|
|
48
|
+
setPoint(temp) {
|
|
49
|
+
if (isNaN(temp)) {
|
|
50
|
+
return NaN;
|
|
51
|
+
}
|
|
52
|
+
this._Tref = temp;
|
|
53
|
+
return this._Tref;
|
|
54
|
+
}
|
|
55
|
+
calculate(actualTemperature) {
|
|
56
|
+
const ePrev = this._e; // Save the error for the next loop
|
|
57
|
+
this._e = this._Tref - actualTemperature; // Calculate the actual error
|
|
58
|
+
// Calculate the P
|
|
59
|
+
this._P = this._Kp * this._e;
|
|
60
|
+
if (this._P > this._MaxP) {
|
|
61
|
+
this._P = this._MaxP;
|
|
62
|
+
}
|
|
63
|
+
else if (this._P < -1 * this._MaxP) {
|
|
64
|
+
this._P = -1 * this._MaxP;
|
|
65
|
+
}
|
|
66
|
+
// Calculate the D
|
|
67
|
+
this._D = this._Kd * (this._e - ePrev);
|
|
68
|
+
if (this._D > this._MaxD) {
|
|
69
|
+
this._D = this._MaxD;
|
|
70
|
+
}
|
|
71
|
+
else if (this._D < -1 * this._MaxD) {
|
|
72
|
+
this._D = -1 * this._MaxD;
|
|
73
|
+
}
|
|
74
|
+
// Calculate the I
|
|
75
|
+
this._I += this._Ki * this._e;
|
|
76
|
+
if (this._I > this._MaxI) {
|
|
77
|
+
this._I = this._MaxI;
|
|
78
|
+
}
|
|
79
|
+
else if (this._I < -1 * this._MaxI) {
|
|
80
|
+
this._I = -1 * this._MaxI;
|
|
81
|
+
}
|
|
82
|
+
// PID algorithm
|
|
83
|
+
this._U = this._P + this._I + this._D;
|
|
84
|
+
// Some value limitation
|
|
85
|
+
if (this._U > this._MaxU) {
|
|
86
|
+
this._U = this._MaxU;
|
|
87
|
+
}
|
|
88
|
+
else if (this._U < 0) {
|
|
89
|
+
// Power cannot be a negative number
|
|
90
|
+
this._U = 0; // this means that the system can only heating
|
|
91
|
+
}
|
|
92
|
+
// Calculate the output
|
|
93
|
+
// and transform U to the [0..1] interval
|
|
94
|
+
return (this._U / 1000) * this._Pmax;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.PIDController = PIDController;
|
|
@@ -14,6 +14,7 @@ class HeaterSettings extends deviceSettings_1.DeviceSettings {
|
|
|
14
14
|
* @type {boolean}
|
|
15
15
|
*/
|
|
16
16
|
this.controlByPid = false;
|
|
17
|
+
this.controlByTempDiff = false;
|
|
17
18
|
/**
|
|
18
19
|
* Whether this device should turn off at Start of summer season and only heat in winter
|
|
19
20
|
* @type {boolean}
|
|
@@ -4,7 +4,7 @@ import { DeviceType } from '../deviceType';
|
|
|
4
4
|
import { IoBrokerDeviceInfo } from '../IoBrokerDeviceInfo';
|
|
5
5
|
export declare class HmIPDevice extends IoBrokerBaseDevice {
|
|
6
6
|
lowBattery: boolean;
|
|
7
|
-
stateMap: Map<string, ioBroker.
|
|
7
|
+
stateMap: Map<string, ioBroker.State>;
|
|
8
8
|
constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
|
|
9
9
|
update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
|
|
10
10
|
}
|
|
@@ -24,7 +24,7 @@ class HmIPDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
|
|
|
24
24
|
}
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
27
|
-
this.stateMap.set(combinedStateName, state
|
|
27
|
+
this.stateMap.set(combinedStateName, state);
|
|
28
28
|
const individualCallbacks = this.individualStateCallbacks.get(combinedStateName);
|
|
29
29
|
if (individualCallbacks !== undefined) {
|
|
30
30
|
for (const cb of individualCallbacks) {
|
|
@@ -6,7 +6,7 @@ export declare class ZigbeeDevice extends IoBrokerBaseDevice {
|
|
|
6
6
|
available: boolean;
|
|
7
7
|
linkQuality: number;
|
|
8
8
|
voltage: string;
|
|
9
|
-
stateMap: Map<string, ioBroker.
|
|
9
|
+
stateMap: Map<string, ioBroker.State>;
|
|
10
10
|
constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
|
|
11
11
|
update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
|
|
12
12
|
}
|
|
@@ -33,7 +33,7 @@ class ZigbeeDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
|
|
|
33
33
|
this.voltage = state.val.toString();
|
|
34
34
|
break;
|
|
35
35
|
}
|
|
36
|
-
this.stateMap.set(idSplit[3], state
|
|
36
|
+
this.stateMap.set(idSplit[3], state);
|
|
37
37
|
const individualCallbacks = this.individualStateCallbacks.get(idSplit[3]);
|
|
38
38
|
if (individualCallbacks !== undefined) {
|
|
39
39
|
for (const cb of individualCallbacks) {
|
|
@@ -5,6 +5,7 @@ import { iBatteryDevice, iHeater } from '../../baseDeviceInterfaces';
|
|
|
5
5
|
import { HeaterSettings, TemperatureSettings } from '../../../../models';
|
|
6
6
|
import { DeviceType } from '../../deviceType';
|
|
7
7
|
import { IoBrokerDeviceInfo } from '../../IoBrokerDeviceInfo';
|
|
8
|
+
import { PIDController } from 'liquid-pid';
|
|
8
9
|
export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater, iBatteryDevice {
|
|
9
10
|
settings: HeaterSettings;
|
|
10
11
|
battery: number;
|
|
@@ -17,6 +18,7 @@ export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater, iBatt
|
|
|
17
18
|
protected _setPointTemperaturID: string;
|
|
18
19
|
protected _temperatur: number;
|
|
19
20
|
protected _desiredTemperatur: number;
|
|
21
|
+
protected _pidController: PIDController;
|
|
20
22
|
constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
|
|
21
23
|
protected _seasonTurnOff: boolean;
|
|
22
24
|
get seasonTurnOff(): boolean;
|
|
@@ -37,5 +39,6 @@ export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater, iBatt
|
|
|
37
39
|
stopAutomaticCheck(): void;
|
|
38
40
|
onTemperaturChange(newTemperatur: number): void;
|
|
39
41
|
update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
|
|
42
|
+
protected getNextPidLevel(): number;
|
|
40
43
|
private checkSeasonTurnOff;
|
|
41
44
|
}
|
|
@@ -6,6 +6,7 @@ const baseDeviceInterfaces_1 = require("../../baseDeviceInterfaces");
|
|
|
6
6
|
const models_1 = require("../../../../models");
|
|
7
7
|
const services_1 = require("../../../services");
|
|
8
8
|
const DeviceCapability_1 = require("../../DeviceCapability");
|
|
9
|
+
const liquid_pid_1 = require("liquid-pid");
|
|
9
10
|
class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
|
|
10
11
|
constructor(pInfo, pType) {
|
|
11
12
|
super(pInfo, pType);
|
|
@@ -17,6 +18,16 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
|
|
|
17
18
|
this._setPointTemperaturID = '';
|
|
18
19
|
this._temperatur = 0;
|
|
19
20
|
this._desiredTemperatur = baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE;
|
|
21
|
+
this._pidController = new liquid_pid_1.PIDController({
|
|
22
|
+
temp: {
|
|
23
|
+
ref: 20, // Point temperature
|
|
24
|
+
},
|
|
25
|
+
Pmax: 100,
|
|
26
|
+
// Tune the PID Controller
|
|
27
|
+
Kp: 25,
|
|
28
|
+
Ki: 1000,
|
|
29
|
+
Kd: 9, // PID: Kd in 1/1000
|
|
30
|
+
});
|
|
20
31
|
this._seasonTurnOff = false;
|
|
21
32
|
this._humidity = 0;
|
|
22
33
|
this._roomTemperatur = 0;
|
|
@@ -115,6 +126,15 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
|
|
|
115
126
|
}
|
|
116
127
|
super.update(idSplit, state, initial, pOverride);
|
|
117
128
|
}
|
|
129
|
+
getNextPidLevel() {
|
|
130
|
+
if (this.seasonTurnOff) {
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
this._pidController.setPoint(this.desiredTemperature);
|
|
134
|
+
const newValue = this._pidController.calculate(this._roomTemperatur);
|
|
135
|
+
this.log(models_1.LogLevel.Debug, `New PID Value ${newValue}% (cTemp: ${this._roomTemperatur}, dTemp: ${this.desiredTemperature})`);
|
|
136
|
+
return newValue;
|
|
137
|
+
}
|
|
118
138
|
checkSeasonTurnOff() {
|
|
119
139
|
const desiredState = services_1.Utils.beetweenDays(new Date(), this.settings.seasonTurnOffDay, this.settings.seasonTurnOnDay);
|
|
120
140
|
if (desiredState !== this.seasonTurnOff || !this._initialSeasonCheckDone) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="iobroker" />
|
|
2
2
|
import { ActuatorSettings, ExcessEnergyConsumerSettings } from '../../../models';
|
|
3
|
-
import {
|
|
3
|
+
import { ZigbeeActuator } from './BaseDevices';
|
|
4
4
|
import { iExcessEnergyConsumer } from '../baseDeviceInterfaces';
|
|
5
5
|
import { IoBrokerDeviceInfo } from '../IoBrokerDeviceInfo';
|
|
6
|
-
export declare class ZigbeeBlitzShp extends
|
|
6
|
+
export declare class ZigbeeBlitzShp extends ZigbeeActuator implements iExcessEnergyConsumer {
|
|
7
7
|
steckerOn: boolean;
|
|
8
8
|
current: number;
|
|
9
9
|
energy: number;
|
|
@@ -11,15 +11,12 @@ export declare class ZigbeeBlitzShp extends ZigbeeDevice implements iExcessEnerg
|
|
|
11
11
|
settings: ActuatorSettings;
|
|
12
12
|
energyConsumerSettings: ExcessEnergyConsumerSettings;
|
|
13
13
|
private readonly _availableForExcessEnergy;
|
|
14
|
-
private readonly steckerOnSwitchID;
|
|
15
14
|
private _activatedByExcessEnergy;
|
|
16
15
|
constructor(pInfo: IoBrokerDeviceInfo);
|
|
17
16
|
get currentConsumption(): number;
|
|
18
17
|
get on(): boolean;
|
|
19
18
|
isAvailableForExcessEnergy(): boolean;
|
|
20
19
|
update(idSplit: string[], state: ioBroker.State, initial?: boolean): void;
|
|
21
|
-
setStecker(pValue: boolean): void;
|
|
22
|
-
toggleStecker(): boolean;
|
|
23
20
|
turnOnForExcessEnergy(): void;
|
|
24
21
|
turnOffDueToMissingEnergy(): void;
|
|
25
22
|
wasActivatedByExcessEnergy(): boolean;
|
|
@@ -5,9 +5,9 @@ const deviceType_1 = require("../deviceType");
|
|
|
5
5
|
const models_1 = require("../../../models");
|
|
6
6
|
const BaseDevices_1 = require("./BaseDevices");
|
|
7
7
|
const DeviceCapability_1 = require("../DeviceCapability");
|
|
8
|
-
class ZigbeeBlitzShp extends BaseDevices_1.
|
|
8
|
+
class ZigbeeBlitzShp extends BaseDevices_1.ZigbeeActuator {
|
|
9
9
|
constructor(pInfo) {
|
|
10
|
-
super(pInfo, deviceType_1.DeviceType.ZigbeeBlitzShp);
|
|
10
|
+
super(pInfo, deviceType_1.DeviceType.ZigbeeBlitzShp, `${pInfo.fullID}.state`);
|
|
11
11
|
this.steckerOn = false;
|
|
12
12
|
this.current = 0;
|
|
13
13
|
this.energy = 0;
|
|
@@ -15,10 +15,8 @@ class ZigbeeBlitzShp extends BaseDevices_1.ZigbeeDevice {
|
|
|
15
15
|
this.settings = new models_1.ActuatorSettings();
|
|
16
16
|
this.energyConsumerSettings = new models_1.ExcessEnergyConsumerSettings();
|
|
17
17
|
this._availableForExcessEnergy = true;
|
|
18
|
-
this.steckerOnSwitchID = '';
|
|
19
18
|
this._activatedByExcessEnergy = false;
|
|
20
19
|
this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.excessEnergyConsumer);
|
|
21
|
-
this.steckerOnSwitchID = `${this.info.fullID}.state`;
|
|
22
20
|
}
|
|
23
21
|
get currentConsumption() {
|
|
24
22
|
return this.loadPower;
|
|
@@ -55,30 +53,12 @@ class ZigbeeBlitzShp extends BaseDevices_1.ZigbeeDevice {
|
|
|
55
53
|
break;
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
|
-
setStecker(pValue) {
|
|
59
|
-
if (this.steckerOnSwitchID === '') {
|
|
60
|
-
this.log(models_1.LogLevel.Error, `Keine Switch ID bekannt.`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
this.log(models_1.LogLevel.Debug, `Switch outlet, target Value: ${pValue}`);
|
|
64
|
-
if (!pValue) {
|
|
65
|
-
this._activatedByExcessEnergy = false;
|
|
66
|
-
}
|
|
67
|
-
this.setState(this.steckerOnSwitchID, pValue, undefined, (err) => {
|
|
68
|
-
this.log(models_1.LogLevel.Error, `Switching outlet resulted in error: ${err}`);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
toggleStecker() {
|
|
72
|
-
const newVal = !this.steckerOn;
|
|
73
|
-
this.setStecker(newVal);
|
|
74
|
-
return newVal;
|
|
75
|
-
}
|
|
76
56
|
turnOnForExcessEnergy() {
|
|
77
57
|
this._activatedByExcessEnergy = true;
|
|
78
|
-
this.
|
|
58
|
+
this.setActuator(true);
|
|
79
59
|
}
|
|
80
60
|
turnOffDueToMissingEnergy() {
|
|
81
|
-
this.
|
|
61
|
+
this.setActuator(false);
|
|
82
62
|
}
|
|
83
63
|
wasActivatedByExcessEnergy() {
|
|
84
64
|
return this._activatedByExcessEnergy;
|
|
@@ -8,14 +8,18 @@ export declare class ZigbeeEuroHeater extends ZigbeeHeater {
|
|
|
8
8
|
private _localDiffTempVal;
|
|
9
9
|
private _setModeId;
|
|
10
10
|
private _valvePosId;
|
|
11
|
+
private _lastRecalc;
|
|
11
12
|
private _mode;
|
|
13
|
+
private _recalcTimeout;
|
|
12
14
|
constructor(pInfo: IoBrokerDeviceInfo);
|
|
15
|
+
get seasonTurnOff(): boolean;
|
|
13
16
|
set seasonTurnOff(value: boolean);
|
|
14
17
|
set roomTemperatur(value: number);
|
|
15
18
|
get desiredTemperature(): number;
|
|
16
19
|
set desiredTemperature(val: number);
|
|
17
20
|
private get tempDiff();
|
|
18
21
|
update(idSplit: string[], state: ioBroker.State, initial?: boolean): void;
|
|
22
|
+
recalcLevel(): void;
|
|
19
23
|
private checkTempDiff;
|
|
20
24
|
private setLocalDiff;
|
|
21
25
|
private setTargetTemperatur;
|
|
@@ -12,12 +12,17 @@ class ZigbeeEuroHeater extends BaseDevices_1.ZigbeeHeater {
|
|
|
12
12
|
this._targetTempVal = baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE;
|
|
13
13
|
this._localTempVal = baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE;
|
|
14
14
|
this._localDiffTempVal = 0;
|
|
15
|
+
this._lastRecalc = 0;
|
|
15
16
|
this._mode = 1;
|
|
17
|
+
this._recalcTimeout = null;
|
|
16
18
|
this._setPointTemperaturID = `${this.info.fullID}.heating_setpnt_current`;
|
|
17
19
|
this._setLocalTempCalibrationId = `${this.info.fullID}.local_temp_calibration`;
|
|
18
20
|
this._setModeId = `${this.info.fullID}.spz_trv_mode`;
|
|
19
21
|
this._valvePosId = `${this.info.fullID}.valve_position`;
|
|
20
22
|
}
|
|
23
|
+
get seasonTurnOff() {
|
|
24
|
+
return this._seasonTurnOff;
|
|
25
|
+
}
|
|
21
26
|
set seasonTurnOff(value) {
|
|
22
27
|
this._seasonTurnOff = value;
|
|
23
28
|
if (value) {
|
|
@@ -36,17 +41,25 @@ class ZigbeeEuroHeater extends BaseDevices_1.ZigbeeHeater {
|
|
|
36
41
|
if (this.settings.useOwnTemperatur) {
|
|
37
42
|
return;
|
|
38
43
|
}
|
|
39
|
-
this.
|
|
44
|
+
this.recalcLevel();
|
|
40
45
|
}
|
|
41
46
|
get desiredTemperature() {
|
|
42
47
|
return this._desiredTemperatur;
|
|
43
48
|
}
|
|
44
49
|
set desiredTemperature(val) {
|
|
45
50
|
this._desiredTemperatur = val;
|
|
46
|
-
this.
|
|
51
|
+
this.recalcLevel();
|
|
47
52
|
}
|
|
48
53
|
get tempDiff() {
|
|
49
|
-
|
|
54
|
+
var _a, _b, _c, _d;
|
|
55
|
+
const tempChangeMs = (_b = (_a = this.stateMap.get('local_temp')) === null || _a === void 0 ? void 0 : _a.lc) !== null && _b !== void 0 ? _b : 0;
|
|
56
|
+
const calibChangeMs = (_d = (_c = this.stateMap.get('local_temp_calibration')) === null || _c === void 0 ? void 0 : _c.lc) !== null && _d !== void 0 ? _d : 0;
|
|
57
|
+
if (tempChangeMs < calibChangeMs) {
|
|
58
|
+
return this._targetTempVal - (this._localTempVal + this._localDiffTempVal);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return this._targetTempVal - this._localTempVal;
|
|
62
|
+
}
|
|
50
63
|
}
|
|
51
64
|
update(idSplit, state, initial = false) {
|
|
52
65
|
switch (idSplit[3]) {
|
|
@@ -82,16 +95,33 @@ class ZigbeeEuroHeater extends BaseDevices_1.ZigbeeHeater {
|
|
|
82
95
|
this.log(models_1.LogLevel.Trace, `Euro Valve Target_Temp Update for ${this.info.customName} to "${state.val}"`);
|
|
83
96
|
this._targetTempVal = state.val;
|
|
84
97
|
if (!initial)
|
|
85
|
-
this.checkTempDiff();
|
|
98
|
+
this.checkTempDiff(); // TODO: If we change it this results in an infinite loop
|
|
86
99
|
break;
|
|
87
100
|
}
|
|
88
101
|
super.update(idSplit, state, initial, true);
|
|
89
102
|
}
|
|
90
|
-
|
|
91
|
-
return; // TODO: Fix this
|
|
103
|
+
recalcLevel() {
|
|
92
104
|
if (this.settings.useOwnTemperatur || this.seasonTurnOff) {
|
|
93
105
|
return;
|
|
94
106
|
}
|
|
107
|
+
const msTilNextMinimumCheck = this._lastRecalc + 5 * 60 * 1000 - services_1.Utils.nowMS();
|
|
108
|
+
if (msTilNextMinimumCheck > 0) {
|
|
109
|
+
if (this._recalcTimeout == null) {
|
|
110
|
+
this._recalcTimeout = services_1.Utils.guardedTimeout(this.recalcLevel, msTilNextMinimumCheck, this);
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (this.settings.controlByPid) {
|
|
115
|
+
this.setValve(this.getNextPidLevel());
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.checkTempDiff();
|
|
119
|
+
}
|
|
120
|
+
checkTempDiff() {
|
|
121
|
+
if (!this.settings.controlByTempDiff) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this._lastRecalc = services_1.Utils.nowMS();
|
|
95
125
|
const desiredDiff = services_1.Utils.round(this.desiredTemperature - this._roomTemperatur, 1);
|
|
96
126
|
const currentDiff = this.tempDiff;
|
|
97
127
|
const missingDiff = services_1.Utils.round(desiredDiff - currentDiff, 1);
|