@uncaught/gpio-shutter-bridge 1.2.0 → 1.2.2
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.
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Gpio } from 'onoff';
|
|
2
2
|
import { ShutterState, ShutterInterfaceWithState, ShutterInterfaceWithPosition, ShutterPosition } from './Shutter.js';
|
|
3
3
|
interface Durations {
|
|
4
|
+
bottomSignalDurations?: number[];
|
|
4
5
|
topFullCloseDurations?: number[];
|
|
5
6
|
topFullOpenDurations?: number[];
|
|
6
|
-
topSignalDurations?: number[];
|
|
7
7
|
}
|
|
8
8
|
export interface Persistence extends Durations {
|
|
9
9
|
position?: number;
|
|
@@ -34,7 +34,7 @@ export declare class VeluxShutter implements ShutterInterfaceWithState, ShutterI
|
|
|
34
34
|
private notifyPositionChange;
|
|
35
35
|
private storeDuration;
|
|
36
36
|
private getAverageDuration;
|
|
37
|
-
private
|
|
37
|
+
private getEstimatedActionDuration;
|
|
38
38
|
private getPositionDelta;
|
|
39
39
|
private setState;
|
|
40
40
|
private clearPositioningTimeout;
|
|
@@ -2,6 +2,14 @@ import { Gpio } from 'onoff';
|
|
|
2
2
|
import { isShutterPosition, isShutterAction, } from './Shutter.js';
|
|
3
3
|
import { press } from '../Gpio.js';
|
|
4
4
|
const durationsToKeep = 20;
|
|
5
|
+
const getBottomDurations = (d) => d.sort((a, b) => a - b).slice(0, durationsToKeep);
|
|
6
|
+
const getLastDurations = (d) => d.slice(-durationsToKeep);
|
|
7
|
+
const getTopDurations = (d) => d.sort((a, b) => b - a).slice(0, durationsToKeep);
|
|
8
|
+
const durationHandlers = {
|
|
9
|
+
bottomSignalDurations: getBottomDurations,
|
|
10
|
+
topFullCloseDurations: getTopDurations,
|
|
11
|
+
topFullOpenDurations: getTopDurations,
|
|
12
|
+
};
|
|
5
13
|
function minMaxPercentage(num) {
|
|
6
14
|
return Math.min(Math.max(num, 0), 100);
|
|
7
15
|
}
|
|
@@ -74,10 +82,7 @@ export class VeluxShutter {
|
|
|
74
82
|
}
|
|
75
83
|
storeDuration(key, duration) {
|
|
76
84
|
if (duration > 0) {
|
|
77
|
-
|
|
78
|
-
this.store.set({
|
|
79
|
-
[key]: [...(this.store.get()[key] ?? []), duration].sort((a, b) => b - a).slice(0, durationsToKeep),
|
|
80
|
-
});
|
|
85
|
+
this.store.set({ [key]: durationHandlers[key]([...(this.store.get()[key] ?? []), duration]) });
|
|
81
86
|
}
|
|
82
87
|
}
|
|
83
88
|
getAverageDuration(key) {
|
|
@@ -88,18 +93,20 @@ export class VeluxShutter {
|
|
|
88
93
|
}
|
|
89
94
|
return 0;
|
|
90
95
|
}
|
|
91
|
-
|
|
96
|
+
getEstimatedActionDuration(action) {
|
|
97
|
+
const signalDuration = this.getAverageDuration('bottomSignalDurations');
|
|
98
|
+
let avg = 0;
|
|
92
99
|
if (action === 'opening') {
|
|
93
|
-
|
|
100
|
+
avg = this.getAverageDuration('topFullOpenDurations');
|
|
94
101
|
}
|
|
95
102
|
if (action === 'closing') {
|
|
96
|
-
|
|
103
|
+
avg = this.getAverageDuration('topFullCloseDurations');
|
|
97
104
|
}
|
|
98
|
-
return 0;
|
|
105
|
+
return avg > 0 ? Math.max(0, avg - signalDuration) : 0;
|
|
99
106
|
}
|
|
100
107
|
getPositionDelta(prevState, duration) {
|
|
101
108
|
if (isShutterAction(prevState) && duration > 0) {
|
|
102
|
-
const avg = this.
|
|
109
|
+
const avg = this.getEstimatedActionDuration(prevState);
|
|
103
110
|
if (avg > 0) {
|
|
104
111
|
return minMaxPercentage(Math.round((duration / avg) * 100));
|
|
105
112
|
}
|
|
@@ -118,7 +125,7 @@ export class VeluxShutter {
|
|
|
118
125
|
//Measure the time it takes between a manual "stop" and the following stopped signal.
|
|
119
126
|
// This gives us an estimate on how long the KLF 150 takes to send it for any operation.
|
|
120
127
|
const stopDuration = this.lastStoppingStartTime ? Date.now() - this.lastStoppingStartTime : 0;
|
|
121
|
-
this.storeDuration('
|
|
128
|
+
this.storeDuration('bottomSignalDurations', stopDuration);
|
|
122
129
|
}
|
|
123
130
|
else {
|
|
124
131
|
this.lastStoppingStartTime = 0;
|
|
@@ -131,7 +138,7 @@ export class VeluxShutter {
|
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
if (isShutterPosition(state)) {
|
|
134
|
-
const signalDuration = this.getAverageDuration('
|
|
141
|
+
const signalDuration = this.getAverageDuration('bottomSignalDurations');
|
|
135
142
|
const measuredDuration = this.lastActionStartTime ? Date.now() - this.lastActionStartTime : 0;
|
|
136
143
|
const positionDuration = measuredDuration > 0 ? Math.max(0, measuredDuration - signalDuration) : 0;
|
|
137
144
|
if (state === 'closed') {
|
|
@@ -205,11 +212,11 @@ export class VeluxShutter {
|
|
|
205
212
|
else if (position > 0 && position < 100) {
|
|
206
213
|
let timeout = 0;
|
|
207
214
|
if (position > this.position) {
|
|
208
|
-
timeout = (this.
|
|
215
|
+
timeout = (this.getEstimatedActionDuration('opening') * (position - this.position)) / 100;
|
|
209
216
|
this.open();
|
|
210
217
|
}
|
|
211
218
|
else {
|
|
212
|
-
timeout = (this.
|
|
219
|
+
timeout = (this.getEstimatedActionDuration('closing') * (this.position - position)) / 100;
|
|
213
220
|
this.close();
|
|
214
221
|
}
|
|
215
222
|
if (timeout) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uncaught/gpio-shutter-bridge",
|
|
3
3
|
"author": "uncaught <uncaught42@gmail.com>",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.2",
|
|
6
6
|
"description": "MQTT shutter bridge for home assistant with Velux KLF 150 support",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|