hoffmation-base 0.1.10 → 0.1.14

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.
@@ -31,20 +31,3 @@ jobs:
31
31
  - run: npm publish
32
32
  env:
33
33
  NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34
-
35
- publish-gpr:
36
- needs: build
37
- runs-on: ubuntu-latest
38
- permissions:
39
- contents: read
40
- packages: write
41
- steps:
42
- - uses: actions/checkout@v2
43
- - uses: actions/setup-node@v2
44
- with:
45
- node-version: 14
46
- registry-url: https://npm.pkg.github.com/
47
- - run: npm ci
48
- - run: npm publish
49
- env:
50
- NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -1,4 +1,4 @@
1
- export class LampSettings {
1
+ export class ActuatorSettings {
2
2
  public dawnOn: boolean = true;
3
3
  public duskOn: boolean = true;
4
4
  public nightOn: boolean = true;
@@ -18,6 +18,7 @@ import { Persist } from '../../server/services/dbo/persist';
18
18
  import { TimeCallbackService, TimeOfDay } from '../../server/services/time-callback-service';
19
19
  import { SonosService } from '../../server/services/Sonos/sonos-service';
20
20
  import { SonosGroup } from '../../server/devices/groups/sonosGroup';
21
+ import { ioBrokerBaseDevice } from '../../server/devices/iIoBrokerDevice';
21
22
 
22
23
  export class RoomBase {
23
24
  public static Rooms: { [name: string]: RoomBase } = {};
@@ -136,7 +137,7 @@ export class RoomBase {
136
137
  );
137
138
  }
138
139
 
139
- public static startIntrusionAlarm(room: RoomBase, device: HmIPDevice): void {
140
+ public static startIntrusionAlarm(room: RoomBase, device: ioBrokerBaseDevice): void {
140
141
  const message: string = `!Potenzieller Eindringling! Bewegung in ${room.roomName} von ${device.info.fullName} festgestellt`;
141
142
  ServerLogService.writeLog(LogLevel.Info, message);
142
143
  if (!this.awayModeActive && !this.nightAlarmActive) {
@@ -47,7 +47,7 @@ export class TimeCallback {
47
47
  let fixedSRDate: Date = new Date(TimeCallbackService.nextSunRise.getTime() + this.minuteOffset * 60 * 1000);
48
48
  if (this.sunTimeOffset) {
49
49
  const nextMinSR: Date = this.sunTimeOffset.getNextMinimumSunrise();
50
- if (fixedSRDate.getDate() === nextMinSR.getDate()) {
50
+ if (nextMinSR > fixedSRDate && fixedSRDate.getDate() === nextMinSR.getDate()) {
51
51
  fixedSRDate = nextMinSR;
52
52
  }
53
53
  }
@@ -65,7 +65,7 @@ export class TimeCallback {
65
65
  let fixedSSDate: Date = new Date(TimeCallbackService.nextSunSet.getTime() + this.minuteOffset * 60 * 1000);
66
66
  if (this.sunTimeOffset) {
67
67
  const nextMaxSS: Date = this.sunTimeOffset.getNextMaximumSunset();
68
- if (fixedSSDate.getDate() === nextMaxSS.getDate()) {
68
+ if (nextMaxSS < fixedSSDate && fixedSSDate.getDate() === nextMaxSS.getDate()) {
69
69
  fixedSSDate = nextMaxSS;
70
70
  }
71
71
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hoffmation-base",
3
3
  "description": "Base Libraries and functions for own Hoffmation projects",
4
- "version": "0.1.10",
4
+ "version": "0.1.14",
5
5
  "main": "index.js",
6
6
  "repository": {
7
7
  "type": "git",
@@ -28,6 +28,7 @@ import { ZigbeeBlitzShp } from './zigbee/zigbeeBlitzShp';
28
28
  import { ZigbeeIlluLampe } from './zigbee/zigbeeIlluLampe';
29
29
  import { ZigbeeIlluActuator } from './zigbee/zigbeeIlluActuator';
30
30
  import { iRoomImportEnforcer } from '../../models/rooms/iRoomImportEnforcer';
31
+ import { ZigbeeAquaraMotion } from './zigbee/zigbeeAquaraMotion';
31
32
 
32
33
  export class Devices {
33
34
  public static hmIP: { [id: string]: HmIPDevice } = {};
@@ -106,6 +107,9 @@ export class Devices {
106
107
  case 'AquaraVibra':
107
108
  Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeAquaraVibra(zigbeeInfo);
108
109
  break;
110
+ case 'AquaraMotion':
111
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeAquaraMotion(zigbeeInfo);
112
+ break;
109
113
  case 'IkeaStecker':
110
114
  Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIkeaSteckdose(zigbeeInfo);
111
115
  break;
@@ -6,11 +6,16 @@ import { ServerLogService } from '../../services/log-service';
6
6
  import { LogLevel } from '../../../models/logLevel';
7
7
  import { TimeCallbackService } from '../../services/time-callback-service';
8
8
  import { Utils } from '../../services/utils/utils';
9
+ import { ZigbeeAquaraMotion } from '../zigbee/zigbeeAquaraMotion';
9
10
 
10
11
  export class PraesenzGroup {
11
12
  private _lastMovement: Date = new Date(0);
12
13
 
13
- public constructor(private _room: RoomBase, public Prasenzen: HmIpPraezenz[], public Bewegungen: HmIpBewegung[]) {
14
+ public constructor(
15
+ private _room: RoomBase,
16
+ public Prasenzen: HmIpPraezenz[],
17
+ public Bewegungen: HmIpBewegung[] | ZigbeeAquaraMotion[],
18
+ ) {
14
19
  for (const b of [...Prasenzen, ...Bewegungen]) {
15
20
  b.room = this._room;
16
21
  }
@@ -15,7 +15,8 @@ export class HmIpBewegung extends HmIPDevice implements iIlluminationSensor {
15
15
  private _detectionsToday: number = 0;
16
16
  private _movementDetectedCallback: Array<(pValue: boolean) => void> = [];
17
17
  private static MOVEMENT_DETECTION: string = 'MOTION';
18
- private static CURRENT_ILLUMINATION: string = 'CURRENT_ILLUMINATION';
18
+ private static ILLUMINATION_DURING_MOVEMENT: string = 'CURRENT_ILLUMINATION';
19
+ private static CURRENT_ILLUMINATION: string = 'ILLUMINATION';
19
20
  private initialized: boolean = false;
20
21
  private fallBackTimeout: NodeJS.Timeout | undefined;
21
22
  private _currentIllumination: number = -1;
@@ -3,7 +3,7 @@ import { HmIPDevice } from './hmIpDevice';
3
3
  import { HmIpDeviceType } from './hmIpDeviceType';
4
4
  import { DeviceInfo } from '../DeviceInfo';
5
5
  import { ServerLogService } from '../../services/log-service';
6
- import { LampSettings } from '../../../models/lampSettings';
6
+ import { ActuatorSettings } from '../../../models/actuatorSettings';
7
7
  import { Utils } from '../../services/utils/utils';
8
8
  import { iLamp } from '../iLamp';
9
9
 
@@ -11,7 +11,7 @@ export class HmIpLampe extends HmIPDevice implements iLamp {
11
11
  public lightOn: boolean = false;
12
12
  public queuedLightValue: boolean | null = null;
13
13
  public isStromStoss: boolean = false;
14
- public settings: LampSettings = new LampSettings();
14
+ public settings: ActuatorSettings = new ActuatorSettings();
15
15
  private lightOnSwitchID: string = '';
16
16
  private turnOffTimeout: NodeJS.Timeout | undefined = undefined;
17
17
  private turnOffTime: number = 0;
@@ -9,13 +9,14 @@ import { Utils } from '../../services/utils/utils';
9
9
  import { CurrentIlluminationDataPoint } from '../../../models/persistence/CurrentIlluminationDataPoint';
10
10
  import { iIlluminationSensor } from '../iIlluminationSensor';
11
11
 
12
- export class HmIpPraezenz extends HmIPDevice implements iIlluminationSensor {
12
+ export class HmIpPraezenz extends HmIPDevice implements iIlluminationSensor {
13
13
  public excludeFromNightAlarm: boolean = false;
14
14
  public presenceDetected: boolean = false;
15
15
  private _detectionsToday: number = 0;
16
16
  private _presenceDetectedCallback: Array<(pValue: boolean) => void> = [];
17
17
  private static PRESENCE_DETECTION: string = 'PRESENCE_DETECTION_STATE';
18
- private static CURRENT_ILLUMINATION: string = 'CURRENT_ILLUMINATION';
18
+ private static ILLUMINATION_DURING_MOVEMENT: string = 'CURRENT_ILLUMINATION';
19
+ private static CURRENT_ILLUMINATION: string = 'ILLUMINATION';
19
20
  private presenceStateID: string;
20
21
  private initialized: boolean = false;
21
22
  private _currentIllumination: number = -1;
@@ -1,8 +1,8 @@
1
1
  import { RoomBase } from '../../models/rooms/RoomBase';
2
- import { LampSettings } from '../../models/lampSettings';
2
+ import { ActuatorSettings } from '../../models/actuatorSettings';
3
3
 
4
4
  export interface iLamp {
5
- settings: LampSettings;
5
+ settings: ActuatorSettings;
6
6
  lightOn: boolean;
7
7
  room: RoomBase | undefined;
8
8
 
@@ -4,10 +4,10 @@ import { DeviceInfo } from '../DeviceInfo';
4
4
  import { ZigbeeDeviceType } from './zigbeeDeviceType';
5
5
  import { ServerLogService } from '../../services/log-service';
6
6
  import { Utils } from '../../services/utils/utils';
7
- import { LampSettings } from '../../../models/lampSettings';
7
+ import { ActuatorSettings as ActuatorSettings } from '../../../models/actuatorSettings';
8
8
 
9
9
  export class ZigbeeActuator extends ZigbeeDevice {
10
- public settings: LampSettings = new LampSettings();
10
+ public settings: ActuatorSettings = new ActuatorSettings();
11
11
  protected readonly actuatorOnSwitchID: string;
12
12
  protected queuedValue: boolean | null = null;
13
13
  protected actuatorOn: boolean = false;
@@ -0,0 +1,205 @@
1
+ import { LogLevel } from '../../../models/logLevel';
2
+ import { ServerLogService } from '../../services/log-service';
3
+ import { Persist } from '../../services/dbo/persist';
4
+ import { Utils } from '../../services/utils/utils';
5
+ import { DeviceInfo } from '../DeviceInfo';
6
+ import { ZigbeeDevice } from './zigbeeDevice';
7
+ import { ZigbeeDeviceType } from './zigbeeDeviceType';
8
+ import { iIlluminationSensor } from '../iIlluminationSensor';
9
+ import { RoomBase } from '../../../models/rooms/RoomBase';
10
+ import { CurrentIlluminationDataPoint } from '../../../models/persistence/CurrentIlluminationDataPoint';
11
+ import { CountToday } from '../../../models/persistence/todaysCount';
12
+
13
+ export class ZigbeeAquaraMotion extends ZigbeeDevice implements iIlluminationSensor {
14
+ public movementDetected: boolean = false;
15
+ public excludeFromNightAlarm: boolean = false;
16
+ public room: RoomBase | undefined = undefined;
17
+
18
+ private _timeSinceLastMotion: number = 0;
19
+ private _illuminance: number = 0;
20
+ private _motionTimeout: number = 0;
21
+ private _detectionsToday: number = 0;
22
+
23
+ private _initialized: boolean = false;
24
+ private _movementDetectedCallback: Array<(pValue: boolean) => void> = [];
25
+ private _fallBackTimeout: NodeJS.Timeout | undefined;
26
+
27
+ private occupancyTimeoutID = `occupancy_timeout`;
28
+
29
+ // Currently measured brightness in lux
30
+ public get currentIllumination(): number {
31
+ return this._illuminance;
32
+ }
33
+
34
+ private set currentIllumination(value: number) {
35
+ this._illuminance = value;
36
+ Persist.persistCurrentIllumination(
37
+ new CurrentIlluminationDataPoint(
38
+ this.info.room,
39
+ this.info.devID,
40
+ value,
41
+ new Date(),
42
+ this.room?.LampenGroup.anyLightsOwn() ?? false,
43
+ ),
44
+ );
45
+ }
46
+
47
+ // Time since last motion in seconds
48
+ public get timeSinceLastMotion(): number {
49
+ return this._timeSinceLastMotion;
50
+ }
51
+
52
+ // Time after the last trigger until a motion event gets triggered again
53
+ public get motionTimeout(): number {
54
+ return this._motionTimeout;
55
+ }
56
+
57
+ public set motionTimeout(value: number) {
58
+ if (!this.ioConn) {
59
+ ServerLogService.writeLog(LogLevel.Error, `No connection active for "${this.info.customName}".`);
60
+ return;
61
+ }
62
+
63
+ this.ioConn.setState(this.occupancyTimeoutID, value, (err) => {
64
+ if (err) {
65
+ console.log(`Error occured while setting motion timeout: ${err}`);
66
+ return;
67
+ }
68
+ this._motionTimeout = value;
69
+ });
70
+ }
71
+
72
+ public get detectionsToday(): number {
73
+ return this._detectionsToday;
74
+ }
75
+
76
+ public set detectionsToday(pVal: number) {
77
+ const oldVal: number = this._detectionsToday;
78
+ this._detectionsToday = pVal;
79
+ Persist.persistTodayCount(this, pVal, oldVal);
80
+ }
81
+
82
+ public constructor(pInfo: DeviceInfo) {
83
+ super(pInfo, ZigbeeDeviceType.ZigbeeAquaraMotion);
84
+
85
+ this.occupancyTimeoutID = `${this.info.fullID}.${this.occupancyTimeoutID}`;
86
+
87
+ Persist.getCount(this).then((todayCount: CountToday) => {
88
+ this.detectionsToday = todayCount.counter;
89
+ ServerLogService.writeLog(
90
+ LogLevel.Debug,
91
+ `Bewegungscounter "${this.info.customName}" vorinitialisiert mit ${this.detectionsToday}`,
92
+ );
93
+ this._initialized = true;
94
+ });
95
+ }
96
+
97
+ public addMovementCallback(pCallback: (pValue: boolean) => void): void {
98
+ this._movementDetectedCallback.push(pCallback);
99
+ }
100
+
101
+ public updateMovement(newState: boolean): void {
102
+ if (!this._initialized && newState) {
103
+ ServerLogService.writeLog(
104
+ LogLevel.Trace,
105
+ `Bewegung für "${this.info.customName}" erkannt aber die Initialisierung aus der DB ist noch nicht erfolgt --> verzögern`,
106
+ );
107
+ Utils.guardedTimeout(
108
+ () => {
109
+ this.updateMovement(newState);
110
+ },
111
+ 1000,
112
+ this,
113
+ );
114
+ return;
115
+ }
116
+
117
+ if (newState === this.movementDetected) {
118
+ ServerLogService.writeLog(
119
+ LogLevel.Debug,
120
+ `Überspringe Bewegung für "${this.info.customName}" da bereits der Wert ${newState} vorliegt`,
121
+ );
122
+
123
+ if (newState) {
124
+ // Wenn ein Sensor sich nicht von alleine zurücksetzt, hier erzwingen.
125
+ this.resetFallbackTimeout();
126
+ this.startFallbackTimeout();
127
+ }
128
+ return;
129
+ }
130
+
131
+ this.resetFallbackTimeout();
132
+ this.movementDetected = newState;
133
+ ServerLogService.writeLog(LogLevel.Debug, `Neuer Bewegunsstatus Wert für "${this.info.customName}": ${newState}`);
134
+
135
+ if (newState) {
136
+ this.startFallbackTimeout();
137
+ this.detectionsToday++;
138
+ ServerLogService.writeLog(
139
+ LogLevel.Trace,
140
+ `Dies ist die ${this.detectionsToday} Bewegung für "${this.info.customName}"`,
141
+ );
142
+ }
143
+
144
+ for (const c of this._movementDetectedCallback) {
145
+ c(newState);
146
+ }
147
+ }
148
+
149
+ public update(idSplit: string[], state: ioBroker.State, initial: boolean = false): void {
150
+ ServerLogService.writeLog(
151
+ LogLevel.DeepTrace,
152
+ `Stecker Update für "${this.info.customName}": ID: ${idSplit.join('.')} JSON: ${JSON.stringify(state)}`,
153
+ );
154
+ super.update(idSplit, state, initial, true);
155
+ switch (idSplit[3]) {
156
+ case 'occupancy':
157
+ ServerLogService.writeLog(
158
+ LogLevel.Trace,
159
+ `Motion sensor: Update for motion state of ${this.info.customName}: ${state.val}`,
160
+ );
161
+ this.updateMovement(state.val as boolean);
162
+ break;
163
+ case 'no_motion':
164
+ ServerLogService.writeLog(
165
+ LogLevel.Trace,
166
+ `Motion sensor: Update for time since last motion of ${this.info.customName}: ${state.val}`,
167
+ );
168
+ this._timeSinceLastMotion = state.val as number;
169
+ break;
170
+ case 'illumincance':
171
+ ServerLogService.writeLog(
172
+ LogLevel.Trace,
173
+ `Motion sensor: Update for illuminance of ${this.info.customName}: ${state.val}`,
174
+ );
175
+ this.currentIllumination = state.val as number;
176
+ break;
177
+ case 'occupancy_timeout':
178
+ ServerLogService.writeLog(
179
+ LogLevel.Trace,
180
+ `Motion sensor: Update for motion timeout of ${this.info.customName}: ${state.val}`,
181
+ );
182
+ this._illuminance = state.val as number;
183
+ break;
184
+ }
185
+ }
186
+
187
+ private resetFallbackTimeout(): void {
188
+ if (this._fallBackTimeout) {
189
+ ServerLogService.writeLog(LogLevel.Trace, `Fallback Timeout für "${this.info.customName}" zurücksetzen`);
190
+ clearTimeout(this._fallBackTimeout);
191
+ }
192
+ }
193
+
194
+ private startFallbackTimeout(): void {
195
+ this._fallBackTimeout = Utils.guardedTimeout(
196
+ () => {
197
+ ServerLogService.writeLog(LogLevel.Debug, `Benötige Fallback Bewegungs Reset für "${this.info.customName}"`);
198
+ this._fallBackTimeout = undefined;
199
+ this.updateMovement(false);
200
+ },
201
+ 270000,
202
+ this,
203
+ );
204
+ }
205
+ }
@@ -3,14 +3,14 @@ import { ServerLogService } from '../../services/log-service';
3
3
  import { DeviceInfo } from '../DeviceInfo';
4
4
  import { ZigbeeDevice } from './zigbeeDevice';
5
5
  import { ZigbeeDeviceType } from './zigbeeDeviceType';
6
- import { LampSettings } from '../../../models/lampSettings';
6
+ import { ActuatorSettings } from '../../../models/actuatorSettings';
7
7
 
8
8
  export class ZigbeeBlitzShp extends ZigbeeDevice {
9
9
  public steckerOn: boolean = false;
10
10
  public current: number = 0;
11
11
  public energy: number = 0;
12
12
  public loadPower: number = 0;
13
- public settings: LampSettings = new LampSettings();
13
+ public settings: ActuatorSettings = new ActuatorSettings();
14
14
  private steckerOnSwitchID: string = '';
15
15
 
16
16
  public constructor(pInfo: DeviceInfo) {
@@ -10,4 +10,5 @@ export enum ZigbeeDeviceType {
10
10
  ZigbeeBlitzShp = 8,
11
11
  ZigbeeIlluLampe = 9,
12
12
  ZigbeeIlluActuator = 10,
13
+ ZigbeeAquaraMotion = 11,
13
14
  }
@@ -11,6 +11,7 @@ import { RoomDetailInfo } from '../../../models/persistence/RoomDetailInfo';
11
11
  import { DailyMovementCount } from '../../../models/persistence/DailyMovementCount';
12
12
  import { iTemperaturDataPoint } from '../../../models/iTemperaturDataPoint';
13
13
  import { CurrentIlluminationDataPoint } from '../../../models/persistence/CurrentIlluminationDataPoint';
14
+ import { ioBrokerBaseDevice } from '../../devices/iIoBrokerDevice';
14
15
 
15
16
  export const TemperatureHistoryCollection = new Mongo.Collection<TemperaturDataPoint>('TemperaturData');
16
17
  export const HeatGroupCollection = new Mongo.Collection<TemperaturDataPoint>('HeatGroupCollection');
@@ -56,7 +57,7 @@ export class Persist {
56
57
  });
57
58
  }
58
59
 
59
- public static async getCount(device: HmIPDevice): Promise<CountToday> {
60
+ public static async getCount(device: ioBrokerBaseDevice): Promise<CountToday> {
60
61
  const result = new Promise<CountToday>((resolve) => {
61
62
  this.MeteorBound(() => {
62
63
  const options = {
@@ -81,7 +82,7 @@ export class Persist {
81
82
  return result;
82
83
  }
83
84
 
84
- public static persistTodayCount(device: HmIPDevice, count: number, oldCount: number): void {
85
+ public static persistTodayCount(device: ioBrokerBaseDevice, count: number, oldCount: number): void {
85
86
  this.MeteorBound(() => {
86
87
  const result = CountTodayCollection.update(
87
88
  { deviceID: device.info.fullID },