hoffmation-base 0.0.1

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.
Files changed (108) hide show
  1. package/.eslintrc.js +27 -0
  2. package/.prettierrc.js +9 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/index.js +1 -0
  6. package/models/connectionCallbacks.ts +13 -0
  7. package/models/daytime.ts +3 -0
  8. package/models/deviceConfig.ts +8 -0
  9. package/models/dimmerSettings.ts +5 -0
  10. package/models/lampSettings.ts +5 -0
  11. package/models/ledSettings.ts +19 -0
  12. package/models/logLevel.ts +9 -0
  13. package/models/persistence/BasicRoomInfo.ts +3 -0
  14. package/models/persistence/DailyMovementCount.ts +3 -0
  15. package/models/persistence/RoomDetailInfo.ts +4 -0
  16. package/models/persistence/temperaturDataPoint.ts +12 -0
  17. package/models/persistence/todaysCount.ts +3 -0
  18. package/models/rooms/RoomBase.ts +357 -0
  19. package/models/rooms/RoomSettings/RoomSettings.ts +159 -0
  20. package/models/rooms/RoomSettings/hmIPRoomSettings.ts +53 -0
  21. package/models/rooms/RoomSettings/iRoomDefaultSettings.ts +17 -0
  22. package/models/rooms/RoomSettings/readme.md +18 -0
  23. package/models/rooms/RoomSettings/zigbeeRoomSettings.ts +51 -0
  24. package/models/rooms/iRoomImportEnforcer.ts +3 -0
  25. package/models/rooms/readme.md +11 -0
  26. package/models/temperaturSettings.ts +22 -0
  27. package/models/timeCallback.ts +90 -0
  28. package/package.json +57 -0
  29. package/server/config/config-readme.md +19 -0
  30. package/server/config/iConfig.ts +53 -0
  31. package/server/devices/DeviceInfo.ts +66 -0
  32. package/server/devices/Griffe.ts +31 -0
  33. package/server/devices/Heizgruppen.ts +91 -0
  34. package/server/devices/Rollos.ts +48 -0
  35. package/server/devices/deviceUpdater.ts +72 -0
  36. package/server/devices/devices.ts +189 -0
  37. package/server/devices/groups/fensterGroup.ts +175 -0
  38. package/server/devices/groups/heatGroup.ts +32 -0
  39. package/server/devices/groups/lampenGroup.ts +88 -0
  40. package/server/devices/groups/praesenzGroup.ts +182 -0
  41. package/server/devices/groups/smokeGroup.ts +16 -0
  42. package/server/devices/groups/sonosGroup.ts +33 -0
  43. package/server/devices/groups/tasterGroup.ts +48 -0
  44. package/server/devices/groups/waterGroup.ts +16 -0
  45. package/server/devices/hmIPDevices/Fenster.ts +114 -0
  46. package/server/devices/hmIPDevices/FensterPosition.ts +5 -0
  47. package/server/devices/hmIPDevices/TuerPosition.ts +4 -0
  48. package/server/devices/hmIPDevices/hmIpBewegung.ts +126 -0
  49. package/server/devices/hmIPDevices/hmIpDevice.ts +90 -0
  50. package/server/devices/hmIPDevices/hmIpDeviceType.ts +14 -0
  51. package/server/devices/hmIPDevices/hmIpGriff.ts +143 -0
  52. package/server/devices/hmIPDevices/hmIpHeizgruppe.ts +172 -0
  53. package/server/devices/hmIPDevices/hmIpHeizung.ts +69 -0
  54. package/server/devices/hmIPDevices/hmIpLampe.ts +119 -0
  55. package/server/devices/hmIPDevices/hmIpPraezenz.ts +99 -0
  56. package/server/devices/hmIPDevices/hmIpRoll.ts +133 -0
  57. package/server/devices/hmIPDevices/hmIpTaste.ts +72 -0
  58. package/server/devices/hmIPDevices/hmIpTaster.ts +73 -0
  59. package/server/devices/hmIPDevices/hmIpTherm.ts +19 -0
  60. package/server/devices/hmIPDevices/hmIpTuer.ts +115 -0
  61. package/server/devices/hmIPDevices/hmIpWippe.ts +55 -0
  62. package/server/devices/iDeviceUpdater.ts +4 -0
  63. package/server/devices/iIoBrokerDevice.ts +44 -0
  64. package/server/devices/wledDevice.ts +124 -0
  65. package/server/devices/zigbee/ZigbeeActuator.ts +113 -0
  66. package/server/devices/zigbee/zigbeeAquaraVibra.ts +171 -0
  67. package/server/devices/zigbee/zigbeeAquaraWater.ts +94 -0
  68. package/server/devices/zigbee/zigbeeBlitzShp.ts +77 -0
  69. package/server/devices/zigbee/zigbeeDevice.ts +115 -0
  70. package/server/devices/zigbee/zigbeeDeviceType.ts +13 -0
  71. package/server/devices/zigbee/zigbeeHeimanSmoke.ts +99 -0
  72. package/server/devices/zigbee/zigbeeIkeaSteckdose.ts +31 -0
  73. package/server/devices/zigbee/zigbeeIlluActuator.ts +37 -0
  74. package/server/devices/zigbee/zigbeeIlluDimmer.ts +165 -0
  75. package/server/devices/zigbee/zigbeeIlluLampe.ts +33 -0
  76. package/server/devices/zigbee/zigbeeIlluLedRGBCCT.ts +137 -0
  77. package/server/ioBroker/connection.ts +1655 -0
  78. package/server/ioBroker/ioBroker.main.ts +99 -0
  79. package/server/ioBroker/socketIOAuthInfo.ts +5 -0
  80. package/server/ioBroker/socketIOConnectOptions.ts +6 -0
  81. package/server/ioBroker/socketIOLogging.ts +29 -0
  82. package/server/ioBroker/socketIOVisCommand.ts +11 -0
  83. package/server/services/HTTPSOptions.ts +14 -0
  84. package/server/services/Sonos/mp3-server.ts +75 -0
  85. package/server/services/Sonos/polly-service.ts +100 -0
  86. package/server/services/Sonos/sonos-service.ts +199 -0
  87. package/server/services/Telegram/telegram-Commands.ts +215 -0
  88. package/server/services/Telegram/telegram-service.ts +171 -0
  89. package/server/services/Telegram/telegramMessageCalback.ts +11 -0
  90. package/server/services/calendar/m/303/274ll-service.ts +224 -0
  91. package/server/services/dbo/persist.ts +125 -0
  92. package/server/services/https-service.ts +71 -0
  93. package/server/services/log-service.ts +69 -0
  94. package/server/services/news-service.ts +81 -0
  95. package/server/services/settings-service.ts +23 -0
  96. package/server/services/time-callback-service.ts +223 -0
  97. package/server/services/utils/ringstorage.ts +24 -0
  98. package/server/services/utils/utils.ts +52 -0
  99. package/server/services/weather/weather-alert.ts +7 -0
  100. package/server/services/weather/weather-current.ts +26 -0
  101. package/server/services/weather/weather-daily.ts +22 -0
  102. package/server/services/weather/weather-feelsLike.ts +6 -0
  103. package/server/services/weather/weather-hourly.ts +17 -0
  104. package/server/services/weather/weather-item.ts +6 -0
  105. package/server/services/weather/weather-minutes.ts +4 -0
  106. package/server/services/weather/weather-service.ts +277 -0
  107. package/server/services/weather/weather-temp.ts +8 -0
  108. package/tsconfig.json +59 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,27 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser', // Specifies the ESLint parser
3
+ parserOptions: {
4
+ ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
5
+ sourceType: 'module', // Allows for the use of imports
6
+ project: './tsconfig.json',
7
+ },
8
+ extends: [
9
+ 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
10
+ // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
11
+ 'plugin:prettier/recommended',
12
+ ],
13
+ plugins: [],
14
+ rules: {
15
+ 'linebreak-style': 'off',
16
+ '@typescript-eslint/no-inferrable-types': [0],
17
+ '@typescript-eslint/adjacent-overload-signatures': [0],
18
+ },
19
+ overrides: [
20
+ {
21
+ files: ['*.test.ts'],
22
+ rules: {
23
+ '@typescript-eslint/explicit-function-return-type': 'off',
24
+ },
25
+ },
26
+ ],
27
+ };
package/.prettierrc.js ADDED
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ semi: true,
3
+ trailingComma: 'all',
4
+ singleQuote: true,
5
+ printWidth: 120,
6
+ useTabs: false,
7
+ tabWidth: 2,
8
+ endOfLine: 'auto',
9
+ };
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Thiemo Hoffmann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # Hoffmation-Base
package/index.js ADDED
@@ -0,0 +1 @@
1
+ // Nothing here, clone hoffmation and use this as library only
@@ -0,0 +1,13 @@
1
+ export class ConnectionCallbacks {
2
+ public onAuth?: any;
3
+ public onCommand?(
4
+ pInstance: string,
5
+ pCommand: string | number | boolean | any[] | Record<string, any> | null,
6
+ pData: any,
7
+ ): boolean;
8
+ public onConnChange?(pState: boolean): void;
9
+ public onError?: any;
10
+ public onObjectChange?(pId: string, pObj: ioBroker.Object): void;
11
+ public onRefresh?: any;
12
+ public onUpdate?(id: string, state: ioBroker.State): void;
13
+ }
@@ -0,0 +1,3 @@
1
+ export class Daytime {
2
+ public constructor(public hour: number, public minute: number = 0) {}
3
+ }
@@ -0,0 +1,8 @@
1
+ export interface deviceConfig {
2
+ type?: ioBroker.ObjectType;
3
+ _id: string;
4
+ ts?: number;
5
+ from?: string;
6
+ native?: any;
7
+ common?: any & { name: string };
8
+ }
@@ -0,0 +1,5 @@
1
+ export class DimmerSettings {
2
+ public dawnOn: boolean = true;
3
+ public duskOn: boolean = true;
4
+ public nightOn: boolean = true;
5
+ }
@@ -0,0 +1,5 @@
1
+ export class LampSettings {
2
+ public dawnOn: boolean = true;
3
+ public duskOn: boolean = true;
4
+ public nightOn: boolean = true;
5
+ }
@@ -0,0 +1,19 @@
1
+ export class LedSettings {
2
+ public defaultColor: string = '#fbbc32';
3
+ public dayOn: boolean = false;
4
+ public dayBrightness: number = 100;
5
+ public dayColor: string = this.defaultColor;
6
+ public dayColorTemp: number = -1;
7
+ public dawnOn: boolean = true;
8
+ public dawnBrightness: number = 50;
9
+ public dawnColor: string = this.defaultColor;
10
+ public dawnColorTemp: number = -1;
11
+ public duskOn: boolean = true;
12
+ public duskBrightness: number = 50;
13
+ public duskColor: string = this.defaultColor;
14
+ public duskColorTemp: number = -1;
15
+ public nightOn: boolean = true;
16
+ public nightBrightness: number = 2;
17
+ public nightColor: string = '#ff5500';
18
+ public nightColorTemp: number = -1;
19
+ }
@@ -0,0 +1,9 @@
1
+ export enum LogLevel {
2
+ Alert = 0,
3
+ Error = 1,
4
+ Warn = 2,
5
+ Info = 3,
6
+ Debug = 4,
7
+ Trace = 5,
8
+ DeepTrace = 6,
9
+ }
@@ -0,0 +1,3 @@
1
+ export class BasicRoomInfo {
2
+ public constructor(public name: string, public etage: number) {}
3
+ }
@@ -0,0 +1,3 @@
1
+ export class DailyMovementCount {
2
+ constructor(public deviceID: string, public counter: number, public roomName: string, public date: Date) {}
3
+ }
@@ -0,0 +1,4 @@
1
+ export class RoomDetailInfo {
2
+ public heaters: string[] = [];
3
+ public constructor(public name: string, public etage: number) {}
4
+ }
@@ -0,0 +1,12 @@
1
+ import { iTemperaturDataPoint } from '/imports/api/heizung';
2
+
3
+ export class TemperaturDataPoint implements iTemperaturDataPoint {
4
+ constructor(
5
+ public name: string,
6
+ public istTemperatur: number,
7
+ public sollTemperatur: number,
8
+ public level: number,
9
+ public humidity: number,
10
+ public date: Date,
11
+ ) {}
12
+ }
@@ -0,0 +1,3 @@
1
+ export class CountToday {
2
+ constructor(public deviceID: string, public counter: number) {}
3
+ }
@@ -0,0 +1,357 @@
1
+ import { TimeCallback } from '../timeCallback';
2
+ import { HmIPDevice } from '../../server/devices/hmIPDevices/hmIpDevice';
3
+ import { TasterGroup } from '../../server/devices/groups/tasterGroup';
4
+ import { PraesenzGroup } from '../../server/devices/groups/praesenzGroup';
5
+ import { ringStorage } from '../../server/services/utils/ringstorage';
6
+ import { TelegramService } from '../../server/services/Telegram/telegram-service';
7
+ import { HeatGroup } from '../../server/devices/groups/heatGroup';
8
+ import { LogLevel } from '../logLevel';
9
+ import { WaterGroup } from '../../server/devices/groups/waterGroup';
10
+ import { ServerLogService } from '../../server/services/log-service';
11
+ import { Utils } from '../../server/services/utils/utils';
12
+ import { LampenGroup } from '../../server/devices/groups/lampenGroup';
13
+ import { RoomSettings } from './RoomSettings/RoomSettings';
14
+ import { SmokeGroup } from '../../server/devices/groups/smokeGroup';
15
+ import { FensterGroup } from '../../server/devices/groups/fensterGroup';
16
+ import { ZigbeeDevice } from '../../server/devices/zigbee/zigbeeDevice';
17
+ import { Persist } from '../../server/services/dbo/persist';
18
+ import { TimeCallbackService, TimeOfDay } from '../../server/services/time-callback-service';
19
+ import { SonosService } from '../../server/services/Sonos/sonos-service';
20
+ import { SonosGroup } from '../../server/devices/groups/sonosGroup';
21
+
22
+ export class RoomBase {
23
+ public static Rooms: { [name: string]: RoomBase } = {};
24
+ public static allRooms: RoomBase[] = [];
25
+ public static floors: { [level: number]: RoomBase[] } = {};
26
+ public static awayModeActive: boolean = false;
27
+ public static nightAlarmActive: boolean = false;
28
+ public static movementHistory: ringStorage = new ringStorage(15);
29
+ public FensterGroup: FensterGroup = new FensterGroup(this, []);
30
+ public PraesenzGroup: PraesenzGroup = new PraesenzGroup(this, [], []);
31
+ public LampenGroup: LampenGroup = new LampenGroup(this, [], [], []);
32
+ public TasterGroup: TasterGroup = new TasterGroup(this, []);
33
+ public SonosGroup: SonosGroup = new SonosGroup(this, []);
34
+ public SmokeGroup: SmokeGroup = new SmokeGroup(this, []);
35
+ public WaterGroup: WaterGroup = new WaterGroup(this, []);
36
+ public HeatGroup: HeatGroup = new HeatGroup(this, []);
37
+ public Settings: RoomSettings;
38
+ public sonnenAufgangCallback: TimeCallback | undefined;
39
+ public sonnenUntergangCallback: TimeCallback | undefined;
40
+ public sonnenAufgangLichtCallback: TimeCallback | undefined;
41
+ public skipNextRolloUp: boolean = false;
42
+ private static _awayModeTimer: NodeJS.Timeout | undefined;
43
+ private static _nightModeTimer: NodeJS.Timeout | undefined;
44
+ private static _intrusionAlarmActive: boolean = false;
45
+ private static _intrusionAlarmLevel: number = 0;
46
+ private static _intrusionAlarmTimeout: NodeJS.Timeout | undefined;
47
+
48
+ public static registerRoomForDevices(roomSettings: RoomSettings): void {
49
+ if (roomSettings.hmIpSettings !== undefined) {
50
+ HmIPDevice.addRoom(roomSettings.shortName, roomSettings.hmIpSettings);
51
+ }
52
+ if (roomSettings.zigbeeSettings !== undefined) {
53
+ ZigbeeDevice.addRoom(roomSettings.shortName, roomSettings.zigbeeSettings);
54
+ }
55
+ }
56
+
57
+ public static addToRoomList(room: RoomBase): void {
58
+ RoomBase.Rooms[room.roomName] = room;
59
+ }
60
+
61
+ public static getAllRoomsOfFloor(floor: number): Array<RoomBase> {
62
+ return this.floors[floor];
63
+ }
64
+
65
+ /**
66
+ * Set ALl Roolos of a specific floor
67
+ * !!floor -1 sets all rollos in house instead!!
68
+ * @param floor the level on which all rollos shall be changed -1 equals all rooms
69
+ * @param position (0 equals down, 100 up)
70
+ */
71
+ public static setAllRolloOfFloor(floor: number = -1, position: number = 0): void {
72
+ const rooms: RoomBase[] = floor > -1 ? this.getAllRoomsOfFloor(floor) : this.allRooms;
73
+ for (const room of rooms) {
74
+ room.FensterGroup.allRolloToLevel(position, true);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Set ALl Lamps of a specific floor
80
+ * !!floor -1 sets all lamps in house instead!!
81
+ * @param floor the level on which all lamps shall be changed -1 equals all rooms
82
+ * @param status
83
+ */
84
+ public static setAllLampsOfFloor(floor: number, status: boolean = false): void {
85
+ ServerLogService.writeLog(LogLevel.Info, `Schalte alle Lampen in Etage ${floor} auf den Wert ${status}`);
86
+ const rooms: RoomBase[] = floor > -1 ? this.getAllRoomsOfFloor(floor) : this.allRooms;
87
+ for (const room of rooms) {
88
+ room.LampenGroup.setAllLampen(status, -1, true);
89
+ room.LampenGroup.setAllLED(status);
90
+ room.LampenGroup.setAllStecker(status, -1, true);
91
+ }
92
+ }
93
+
94
+ public static clearAllAlarms(): void {
95
+ for (const r of RoomBase.allRooms) {
96
+ if (r.WaterGroup) {
97
+ r.WaterGroup.stopAlarm();
98
+ }
99
+ if (r.SmokeGroup) {
100
+ r.SmokeGroup.stopAlarm();
101
+ }
102
+ }
103
+ this.stopIntrusionAlarm();
104
+ this.restoreRolloPosition();
105
+ this.restoreLight();
106
+ }
107
+
108
+ public static startAwayMode(): void {
109
+ SonosService.speakOnAll(`Alarmanlage wird scharfgeschaltet.`, 40);
110
+ if (this._awayModeTimer) {
111
+ clearTimeout(this._awayModeTimer);
112
+ }
113
+ this._awayModeTimer = Utils.guardedTimeout(
114
+ () => {
115
+ this.awayModeActive = true;
116
+ this._awayModeTimer = undefined;
117
+ TelegramService.inform(`Alarm ist nun scharf. Gute Reise!`);
118
+ },
119
+ 60000,
120
+ this,
121
+ );
122
+ }
123
+ public static startNightAlarmMode(): void {
124
+ SonosService.speakOnAll(`Alarmanlage wird für die Nacht scharfgeschaltet. Gute Nacht!`, 30);
125
+ if (this._nightModeTimer) {
126
+ clearTimeout(this._nightModeTimer);
127
+ }
128
+ this._nightModeTimer = Utils.guardedTimeout(
129
+ () => {
130
+ this.nightAlarmActive = true;
131
+ this._nightModeTimer = undefined;
132
+ TelegramService.inform(`Alarm ist nun scharf. Süße Träume!`);
133
+ },
134
+ 60000,
135
+ this,
136
+ );
137
+ }
138
+
139
+ public static startIntrusionAlarm(room: RoomBase, device: HmIPDevice): void {
140
+ const message: string = `!Potenzieller Eindringling! Bewegung in ${room.roomName} von ${device.info.fullName} festgestellt`;
141
+ ServerLogService.writeLog(LogLevel.Info, message);
142
+ if (!this.awayModeActive && !this.nightAlarmActive) {
143
+ this.stopIntrusionAlarm();
144
+ return;
145
+ }
146
+
147
+ Utils.guardedNewThread(() => {
148
+ TelegramService.inform(message);
149
+ }, this);
150
+
151
+ if (this._intrusionAlarmActive) {
152
+ return;
153
+ }
154
+ this._intrusionAlarmActive = true;
155
+ this.performNextIntrusionLevel();
156
+ }
157
+
158
+ public static endAlarmModes(): void {
159
+ if (this.awayModeActive) {
160
+ TelegramService.sendMessage(TelegramService.subscribedIDs, `Alarmanalage entschärft`);
161
+ SonosService.speakOnAll(`Willkommen Zuhause!`, 35);
162
+ }
163
+ if (this.nightAlarmActive) {
164
+ TelegramService.sendMessage(TelegramService.subscribedIDs, `Nachtmodus der Alarmanlage entschärft`);
165
+ SonosService.speakOnAll(`Guten Morgen!`, 30);
166
+ }
167
+ if (this._nightModeTimer) {
168
+ clearTimeout(this._nightModeTimer);
169
+ }
170
+ if (this._awayModeTimer) {
171
+ clearTimeout(this._awayModeTimer);
172
+ }
173
+ this.awayModeActive = false;
174
+ this.nightAlarmActive = false;
175
+
176
+ this.stopIntrusionAlarm();
177
+ }
178
+
179
+ public static getLastMovements(): string {
180
+ return this.movementHistory.readAmount(15).join('\n');
181
+ }
182
+
183
+ public constructor(public roomName: string, public Einstellungen: RoomSettings) {
184
+ if (Einstellungen.etage !== undefined) {
185
+ const level: number = Einstellungen.etage;
186
+ if (RoomBase.floors[level] === undefined) {
187
+ RoomBase.floors[level] = [];
188
+ }
189
+ RoomBase.floors[level].push(this);
190
+ }
191
+ Einstellungen.room = this;
192
+ this.Settings = Einstellungen;
193
+ RoomBase.allRooms.push(this);
194
+ }
195
+
196
+ public initializeBase(): void {
197
+ ServerLogService.writeLog(LogLevel.Debug, `RoomBase Init für ${this.roomName}`);
198
+ this.recalcTimeCallbacks();
199
+ this.PraesenzGroup.initCallbacks();
200
+ this.FensterGroup.initCallbacks();
201
+ this.TasterGroup.initCallbacks();
202
+ }
203
+
204
+ public persist(): void {
205
+ Persist.addRoom(this);
206
+ }
207
+
208
+ public recalcTimeCallbacks(): void {
209
+ const now: Date = new Date();
210
+ if (this.sonnenAufgangCallback && this.Einstellungen.rolloOffset) {
211
+ this.sonnenAufgangCallback.minuteOffset = this.Einstellungen.rolloOffset.sunrise;
212
+ this.sonnenAufgangCallback.sunTimeOffset = this.Einstellungen.rolloOffset;
213
+ this.sonnenAufgangCallback.recalcNextToDo(now);
214
+ }
215
+ if (this.sonnenUntergangCallback && this.Einstellungen.rolloOffset) {
216
+ this.sonnenUntergangCallback.minuteOffset = this.Einstellungen.rolloOffset.sunset;
217
+ this.sonnenUntergangCallback.sunTimeOffset = this.Einstellungen.rolloOffset;
218
+ this.sonnenUntergangCallback.recalcNextToDo(now);
219
+ }
220
+ if (this.sonnenAufgangLichtCallback && this.Einstellungen.lampOffset) {
221
+ this.sonnenAufgangLichtCallback.minuteOffset = this.Einstellungen.lampOffset.sunrise;
222
+ this.sonnenAufgangLichtCallback.recalcNextToDo(now);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Sets the light based on the current time, rollo Position and room Settings
228
+ * @param movementDependant Only turn light on if there was a movement in the same room
229
+ */
230
+ public setLightTimeBased(movementDependant: boolean = false): void {
231
+ if (movementDependant && !this.PraesenzGroup.anyPresent()) {
232
+ this.LampenGroup.switchAll(false);
233
+ return;
234
+ }
235
+
236
+ if (!this.Einstellungen.lampOffset) {
237
+ ServerLogService.writeLog(
238
+ LogLevel.Alert,
239
+ `Beim Aufruf von "setLightTimeBased" im Raum ${this.roomName} liegt kein Lampen Offset vor`,
240
+ );
241
+ return;
242
+ }
243
+ let timeOfDay: TimeOfDay = TimeCallbackService.dayType(this.Einstellungen.lampOffset);
244
+ if (
245
+ timeOfDay === TimeOfDay.Daylight &&
246
+ ((this.Einstellungen.lightIfNoWindows && this.FensterGroup.fenster.length === 0) ||
247
+ this.FensterGroup.fenster.some((f) => {
248
+ const rolloDown: boolean = f.rollo?.currentLevel === 0;
249
+ ServerLogService.writeLog(
250
+ LogLevel.Debug,
251
+ `Rollo ${f.rollo?.info.customName} for light in ${this.roomName} is ${rolloDown ? '' : 'not '}down`,
252
+ );
253
+ return rolloDown;
254
+ }))
255
+ ) {
256
+ timeOfDay = TimeOfDay.AfterSunset;
257
+ }
258
+ this.LampenGroup.switchTimeConditional(timeOfDay);
259
+ }
260
+
261
+ public isNowLightTime(): boolean {
262
+ if (!this.Einstellungen.lampOffset) {
263
+ ServerLogService.writeLog(
264
+ LogLevel.Alert,
265
+ `Beim Aufruf von "setLightTimeBased" im Raum ${this.roomName} liegt kein Lampen Offset vor`,
266
+ );
267
+ return false;
268
+ }
269
+ let timeOfDay: TimeOfDay = TimeCallbackService.dayType(this.Einstellungen.lampOffset);
270
+ if (
271
+ timeOfDay === TimeOfDay.Daylight &&
272
+ this.FensterGroup.fenster.some((f) => {
273
+ return f.rollo?.currentLevel === 0;
274
+ })
275
+ ) {
276
+ timeOfDay = TimeOfDay.AfterSunset;
277
+ }
278
+ return TimeCallbackService.darkOutsideOrNight(timeOfDay);
279
+ }
280
+
281
+ private static stopIntrusionAlarm() {
282
+ ServerLogService.writeLog(LogLevel.Info, `Stoppe Intrusion Alarm`);
283
+ if (this._intrusionAlarmTimeout) {
284
+ clearTimeout(this._intrusionAlarmTimeout);
285
+ }
286
+ if (!this._intrusionAlarmActive) {
287
+ return;
288
+ }
289
+ this._intrusionAlarmActive = false;
290
+ this._intrusionAlarmLevel = 0;
291
+ ServerLogService.writeLog(LogLevel.Alert, `Alarm wurde beendet --> Fahre Rollos in Ausgangsposition.`);
292
+ this.restoreRolloPosition();
293
+ this.restoreLight();
294
+ }
295
+
296
+ private static performNextIntrusionLevel(): void {
297
+ this._intrusionAlarmTimeout = undefined;
298
+ if (!this.awayModeActive && !this._intrusionAlarmActive) {
299
+ return;
300
+ }
301
+ this._intrusionAlarmLevel += 1;
302
+ let speakMessage: string;
303
+ let volume = 50;
304
+ let newTimeout: number = 20000;
305
+ const alarmAutomaticEnd: number = 15;
306
+ if (this._intrusionAlarmLevel === 1) {
307
+ speakMessage = `Hallo potenzieller Eindringling! Das Alarmprotokoll ist initiiert bitte verlassen Sie umgehend das Gebäude!`;
308
+ volume = 40;
309
+ } else if (this._intrusionAlarmLevel === 2) {
310
+ speakMessage = `Alle Rollos fahren hoch, bitte begeben Sie sich zum nächsten Ausgang`;
311
+ Utils.guardedNewThread(() => {
312
+ this.setAllRolloOfFloor(-1, 100);
313
+ this.setAllLampsOfFloor(-1, true);
314
+ }, this);
315
+ } else if (this._intrusionAlarmLevel === 3) {
316
+ volume = 70;
317
+ speakMessage = `Verlassen Sie sofort das Gebäude! Die Behörden sind informiert`;
318
+ } else if (this._intrusionAlarmLevel <= 5) {
319
+ volume = 80;
320
+ speakMessage = `Weitere Abwehrmaßnahmen werden eingeleitet`;
321
+ } else if (this._intrusionAlarmLevel >= alarmAutomaticEnd) {
322
+ this.stopIntrusionAlarm();
323
+ return;
324
+ } else {
325
+ volume = 90;
326
+ speakMessage = `Alarm. Einbrecher erkannt.`;
327
+ newTimeout = 10000;
328
+ }
329
+ this._intrusionAlarmTimeout = Utils.guardedTimeout(
330
+ () => {
331
+ this.performNextIntrusionLevel();
332
+ },
333
+ newTimeout,
334
+ this,
335
+ );
336
+ Utils.guardedNewThread(() => {
337
+ SonosService.speakOnAll(speakMessage, volume);
338
+ TelegramService.inform(
339
+ `Eindringling erhielt folgende Nachricht: "${speakMessage}"\nAlarmlevel ist ${this._intrusionAlarmLevel}\t Automatisches Ende bei ${alarmAutomaticEnd}`,
340
+ );
341
+ }, this);
342
+ }
343
+
344
+ private static restoreRolloPosition(): void {
345
+ const rooms: RoomBase[] = this.allRooms;
346
+ for (const room of rooms) {
347
+ room.FensterGroup.restoreRolloPosition();
348
+ }
349
+ }
350
+
351
+ private static restoreLight() {
352
+ const rooms: RoomBase[] = this.allRooms;
353
+ for (const room of rooms) {
354
+ room.setLightTimeBased(true);
355
+ }
356
+ }
357
+ }