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
@@ -0,0 +1,182 @@
1
+ import { HmIpPraezenz } from '../hmIPDevices/hmIpPraezenz';
2
+ import { HmIpBewegung } from '../hmIPDevices/hmIpBewegung';
3
+ import { RoomBase } from '../../../models/rooms/RoomBase';
4
+ import { TimeCallback, TimeCallbackType } from '../../../models/timeCallback';
5
+ import { ServerLogService } from '../../services/log-service';
6
+ import { LogLevel } from '../../../models/logLevel';
7
+ import { TimeCallbackService } from '../../services/time-callback-service';
8
+ import { Utils } from '../../services/utils/utils';
9
+
10
+ export class PraesenzGroup {
11
+ private _lastMovement: Date = new Date(0);
12
+
13
+ public constructor(private _room: RoomBase, public Prasenzen: HmIpPraezenz[], public Bewegungen: HmIpBewegung[]) {
14
+ for (const b of [...Prasenzen, ...Bewegungen]) {
15
+ b.room = this._room;
16
+ }
17
+ }
18
+
19
+ public initCallbacks(): void {
20
+ this.Prasenzen.forEach((p) => {
21
+ p.addPresenceCallback((val) => {
22
+ if (!val) {
23
+ return;
24
+ }
25
+ if (RoomBase.awayModeActive || (RoomBase.nightAlarmActive && !p.excludeFromNightAlarm)) {
26
+ RoomBase.startIntrusionAlarm(this._room, p);
27
+ }
28
+ RoomBase.movementHistory.add(`${Utils.nowString()}: Raum "${this._room.roomName}" Gerät "${p.info.fullName}"`);
29
+ });
30
+ });
31
+ this.Bewegungen.forEach((b) => {
32
+ b.addMovementCallback((val) => {
33
+ if (!val) {
34
+ return;
35
+ }
36
+ if (RoomBase.awayModeActive || (RoomBase.nightAlarmActive && !b.excludeFromNightAlarm)) {
37
+ RoomBase.startIntrusionAlarm(this._room, b);
38
+ }
39
+ RoomBase.movementHistory.add(`${Utils.nowString()}: Raum "${this._room.roomName}" Gerät "${b.info.fullName}"`);
40
+ });
41
+ });
42
+ if (this._room.Einstellungen.lichtSonnenAufgangAus && this._room.Einstellungen.lampOffset) {
43
+ this._room.sonnenAufgangLichtCallback = new TimeCallback(
44
+ `${this._room.roomName} Morgens Lampe aus`,
45
+ TimeCallbackType.Sunrise,
46
+ () => {
47
+ ServerLogService.writeLog(
48
+ LogLevel.Info,
49
+ `Es ist hell genug --> Schalte Lampen im ${this._room.roomName} aus`,
50
+ );
51
+ this._room.LampenGroup.switchAll(false);
52
+ },
53
+ this._room.Einstellungen.lampOffset.sunrise,
54
+ );
55
+ TimeCallbackService.addCallback(this._room.sonnenAufgangLichtCallback);
56
+ }
57
+
58
+ this.addLastLeftCallback(() => {
59
+ this._room.LampenGroup.switchAll(false);
60
+ });
61
+
62
+ if (this._room.Einstellungen.lampenBeiBewegung) {
63
+ this.addFirstEnterCallback(() => {
64
+ ServerLogService.writeLog(
65
+ LogLevel.DeepTrace,
66
+ `Bewegung im Raum ${this._room.roomName} festgestellt --> Licht einschalten`,
67
+ );
68
+ this._room.setLightTimeBased();
69
+ });
70
+ }
71
+ }
72
+
73
+ public presentAmount(): number {
74
+ let count = 0;
75
+ for (let i = 0; i < this.Prasenzen.length; i++) {
76
+ if (this.Prasenzen[i].presenceDetected) {
77
+ count++;
78
+ }
79
+ }
80
+ for (let i = 0; i < this.Bewegungen.length; i++) {
81
+ if (this.Bewegungen[i].movementDetected) {
82
+ count++;
83
+ }
84
+ }
85
+
86
+ return count;
87
+ }
88
+
89
+ public anyPresent(): boolean {
90
+ for (let i = 0; i < this.Prasenzen.length; i++) {
91
+ if (this.Prasenzen[i].presenceDetected) {
92
+ return true;
93
+ }
94
+ }
95
+ for (let i = 0; i < this.Bewegungen.length; i++) {
96
+ if (this.Bewegungen[i].movementDetected) {
97
+ return true;
98
+ }
99
+ }
100
+
101
+ return false;
102
+ }
103
+
104
+ public lastLeftCB(val: boolean, cb: () => void): void {
105
+ if (val) {
106
+ return;
107
+ }
108
+
109
+ if (this.anyPresent()) {
110
+ return;
111
+ }
112
+
113
+ let timeAfterReset: number =
114
+ Utils.nowMS() - this._lastMovement.getTime() - this._room.Einstellungen.movementResetTimer * 1000;
115
+ if (timeAfterReset > 0) {
116
+ ServerLogService.writeLog(
117
+ LogLevel.Debug,
118
+ `Movement reset in ${
119
+ this._room.roomName
120
+ }.\nActive Motions: ${this.presentAmount()}\nTime after Last Movement including Reset: ${timeAfterReset}`,
121
+ );
122
+ cb();
123
+ return;
124
+ }
125
+ ServerLogService.writeLog(LogLevel.Debug, `Movement reset in ${this._room.roomName} delayed.`);
126
+ Utils.guardedTimeout(
127
+ () => {
128
+ timeAfterReset =
129
+ Utils.nowMS() - this._lastMovement.getTime() - this._room.Einstellungen.movementResetTimer * 1000;
130
+ ServerLogService.writeLog(
131
+ LogLevel.Debug,
132
+ `Delayed Movement reset in ${
133
+ this._room.roomName
134
+ }.\nActive Motions: ${this.presentAmount()}\nTime after Last Movement including Reset: ${timeAfterReset}`,
135
+ );
136
+ if (!this.anyPresent() && timeAfterReset > 0) {
137
+ cb();
138
+ }
139
+ },
140
+ Math.abs(timeAfterReset) + 500,
141
+ this,
142
+ );
143
+ }
144
+
145
+ public addLastLeftCallback(cb: () => void): void {
146
+ this.Prasenzen.forEach((p) => {
147
+ p.addPresenceCallback((val) => {
148
+ this.lastLeftCB(val, cb);
149
+ });
150
+ });
151
+ this.Bewegungen.forEach((b) => {
152
+ b.addMovementCallback((val) => {
153
+ this.lastLeftCB(val, cb);
154
+ });
155
+ });
156
+ }
157
+
158
+ private firstEnterCallback(val: boolean, cb: () => void): void {
159
+ if (!val) {
160
+ return;
161
+ }
162
+ this._lastMovement = new Date();
163
+ if (this.presentAmount() > 1) {
164
+ return;
165
+ }
166
+
167
+ cb();
168
+ }
169
+
170
+ public addFirstEnterCallback(cb: () => void): void {
171
+ this.Prasenzen.forEach((p) => {
172
+ p.addPresenceCallback((val) => {
173
+ this.firstEnterCallback(val, cb);
174
+ });
175
+ });
176
+ this.Bewegungen.forEach((b) => {
177
+ b.addMovementCallback((val) => {
178
+ this.firstEnterCallback(val, cb);
179
+ });
180
+ });
181
+ }
182
+ }
@@ -0,0 +1,16 @@
1
+ import { ZigbeeHeimanSmoke } from '../zigbee/zigbeeHeimanSmoke';
2
+ import { RoomBase } from '../../../models/rooms/RoomBase';
3
+
4
+ export class SmokeGroup {
5
+ public constructor(private _room: RoomBase, public Rauchmelder: Array<ZigbeeHeimanSmoke>) {
6
+ for (const s of [...this.Rauchmelder]) {
7
+ s.room = this._room;
8
+ }
9
+ }
10
+
11
+ public stopAlarm(): void {
12
+ for (const d of this.Rauchmelder) {
13
+ d.stopAlarm(true);
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,33 @@
1
+ import { OwnSonosDevice } from '../../services/Sonos/sonos-service';
2
+ import { Utils } from '../../services/utils/utils';
3
+ import { RoomBase } from '../../../models/rooms/RoomBase';
4
+
5
+ export class SonosGroup {
6
+ private _playing: boolean = false;
7
+ public constructor(private _room: RoomBase, public ownSonosDevices: OwnSonosDevice[]) {}
8
+
9
+ public playRadio(radioUrl: string): void {
10
+ this.ownSonosDevices.forEach((s) => {
11
+ Utils.guardedTimeout(() => {
12
+ s.device?.SetAVTransportURI(radioUrl);
13
+ }, 1500);
14
+ });
15
+ this._playing = true;
16
+ }
17
+
18
+ public turnOff(): void {
19
+ this.ownSonosDevices.forEach((s) => {
20
+ s.device?.Stop();
21
+ });
22
+ this._playing = false;
23
+ }
24
+
25
+ public trigger(track: string): void {
26
+ if (this._playing) {
27
+ this.turnOff();
28
+ return;
29
+ }
30
+
31
+ this.playRadio(track);
32
+ }
33
+ }
@@ -0,0 +1,48 @@
1
+ import { HmIpTaster } from '../hmIPDevices/hmIpTaster';
2
+ import { RoomBase } from '../../../models/rooms/RoomBase';
3
+
4
+ export class TasterGroup {
5
+ public constructor(private _room: RoomBase, public Taster: HmIpTaster[]) {
6
+ for (const t of [...Taster]) {
7
+ t.room = this._room;
8
+ }
9
+ }
10
+
11
+ public initCallbacks(): void {
12
+ this.Taster.forEach((t) => {
13
+ t.tasten.ObenLinks.addLongCallback((pValue) => {
14
+ pValue && this._room.FensterGroup.allRolloDown(false, true);
15
+ });
16
+
17
+ t.tasten.ObenLinks.addShortCallback((pValue) => {
18
+ pValue && this._room.FensterGroup.allRolloToLevel(25, true);
19
+ });
20
+
21
+ t.tasten.ObenRechts.addLongCallback((pValue) => {
22
+ if (!pValue) {
23
+ return;
24
+ }
25
+
26
+ this._room.FensterGroup.allRolloUp(true);
27
+ });
28
+
29
+ t.tasten.ObenRechts.addShortCallback((pValue) => {
30
+ pValue && this._room.FensterGroup.allRolloToLevel(50, true);
31
+ });
32
+
33
+ t.tasten.MitteLinks.addLongCallback((pValue) => {
34
+ pValue && this._room.LampenGroup.switchAll(true, true);
35
+ });
36
+
37
+ t.tasten.MitteRechts.addLongCallback((pValue) => {
38
+ pValue && this._room.LampenGroup.switchAll(false, true);
39
+ });
40
+
41
+ if (this._room.SonosGroup.SNDevices.length > 0) {
42
+ t.tasten.UntenRechts.addLongCallback(() => {
43
+ this._room.SonosGroup.trigger(this._room.Einstellungen.radioUrl);
44
+ });
45
+ }
46
+ });
47
+ }
48
+ }
@@ -0,0 +1,16 @@
1
+ import { ZigbeeAquaraWater } from '../zigbee/zigbeeAquaraWater';
2
+ import { RoomBase } from '../../../models/rooms/RoomBase';
3
+
4
+ export class WaterGroup {
5
+ public constructor(private _room: RoomBase, public WaterDetectors: Array<ZigbeeAquaraWater>) {
6
+ for (const w of [...WaterDetectors]) {
7
+ w.room = this._room;
8
+ }
9
+ }
10
+
11
+ public stopAlarm(): void {
12
+ for (const d of this.WaterDetectors) {
13
+ d.stopAlarm(true);
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,114 @@
1
+ import { ZigbeeAquaraVibra } from '../zigbee/zigbeeAquaraVibra';
2
+ import { FensterPosition } from './FensterPosition';
3
+ import { HmIpGriff } from './hmIpGriff';
4
+ import { HmIpRoll } from './hmIpRoll';
5
+ import { LogLevel } from '../../../models/logLevel';
6
+ import { ServerLogService } from '../../services/log-service';
7
+ import { TimeCallbackService, TimeOfDay } from '../../services/time-callback-service';
8
+ import { Utils } from '../../services/utils/utils';
9
+ import { RoomBase } from '../../../models/rooms/RoomBase';
10
+
11
+ export class Fenster {
12
+ public desiredPosition: number = 0;
13
+
14
+ /**
15
+ * sets the desired Pos and moves rollo to this level
16
+ * @param {number} value
17
+ */
18
+ public setDesiredPosition(value: number) {
19
+ this.desiredPosition = value;
20
+ this.restoreDesiredPosition();
21
+ }
22
+
23
+ public constructor(
24
+ public room: RoomBase,
25
+ public griffe: HmIpGriff[],
26
+ public vibration: ZigbeeAquaraVibra[],
27
+ public rollo: HmIpRoll | undefined = undefined,
28
+ public noRolloOnSunrise: boolean = false,
29
+ ) {
30
+ for (const griff of griffe) {
31
+ griff.addKippCallback((kipp: boolean) => {
32
+ if (kipp && this.griffeInPosition(FensterPosition.offen) === 0) {
33
+ this.vibration.forEach((element) => {
34
+ element.vibrationBlocked = true;
35
+ });
36
+ const timeOfDay: TimeOfDay = TimeCallbackService.dayType(this.room.Einstellungen.rolloOffset);
37
+ if (TimeCallbackService.darkOutsideOrNight(timeOfDay)) {
38
+ this.rollo?.setLevel(50);
39
+ } else {
40
+ this.rollo?.up();
41
+ }
42
+ }
43
+ });
44
+
45
+ griff.addOffenCallback((offen: boolean) => {
46
+ if (offen) {
47
+ this.vibration.forEach((element) => {
48
+ element.vibrationBlocked = true;
49
+ });
50
+ this.rollo?.up();
51
+ return;
52
+ }
53
+ });
54
+
55
+ griff.addClosedCallback((geschlossen: boolean) => {
56
+ if (
57
+ geschlossen &&
58
+ this.griffeInPosition(FensterPosition.offen) === 0 &&
59
+ this.griffeInPosition(FensterPosition.kipp) === 0
60
+ ) {
61
+ const now = new Date().getTime();
62
+ this.vibration.forEach((element) => {
63
+ ServerLogService.writeLog(
64
+ LogLevel.Debug,
65
+ `Starte Timeout für Vibrationsdeaktivierung für ${element.info.customName}`,
66
+ );
67
+ Utils.guardedTimeout(() => {
68
+ if (element.vibrationBlockedTimeStamp < now) {
69
+ element.vibrationBlocked = false;
70
+ }
71
+ }, 12000);
72
+ });
73
+ this.restoreDesiredPosition();
74
+ }
75
+ });
76
+ }
77
+ Utils.guardedTimeout(
78
+ () => {
79
+ if (this.rollo) this.rollo.Fenster = this;
80
+ for (const g of this.griffe) {
81
+ g.Fenster = this;
82
+ }
83
+ },
84
+ 5,
85
+ this,
86
+ );
87
+ }
88
+
89
+ public griffeInPosition(pPosition: FensterPosition): number {
90
+ let count = 0;
91
+ for (const griff of this.griffe) {
92
+ if (griff.position === pPosition) {
93
+ count++;
94
+ }
95
+ }
96
+ return count;
97
+ }
98
+
99
+ public rolloPositionChange(pValue: number): void {
100
+ if (!this.room) {
101
+ ServerLogService.writeLog(LogLevel.Error, `Fenster Rollo Update, but this one is not connected to any room!`);
102
+ return;
103
+ }
104
+ ServerLogService.writeLog(LogLevel.Debug, `Rollo Position Change in ${this.room.roomName} to ${pValue}`);
105
+
106
+ if (pValue === 0 || pValue === 100) {
107
+ this.room.setLightTimeBased(true);
108
+ }
109
+ }
110
+
111
+ public restoreDesiredPosition() {
112
+ this.rollo?.setLevel(this.desiredPosition);
113
+ }
114
+ }
@@ -0,0 +1,5 @@
1
+ export enum FensterPosition {
2
+ geschlossen = 0,
3
+ kipp = 1,
4
+ offen = 2,
5
+ }
@@ -0,0 +1,4 @@
1
+ export enum TuerPosition {
2
+ geschlossen = 0,
3
+ offen = 1,
4
+ }
@@ -0,0 +1,126 @@
1
+ import { HmIPDevice } from './hmIpDevice';
2
+ import { HmIpDeviceType } from './hmIpDeviceType';
3
+ import { DeviceInfo } from '../DeviceInfo';
4
+ import { LogLevel } from '../../../models/logLevel';
5
+ import { ServerLogService } from '../../services/log-service';
6
+ import { Persist } from '../../services/dbo/persist';
7
+ import { CountToday } from '../../../models/persistence/todaysCount';
8
+ import { Utils } from '../../services/utils/utils';
9
+
10
+ export class HmIpBewegung extends HmIPDevice {
11
+ public excludeFromNightAlarm: boolean = false;
12
+ public movementDetected: boolean = false;
13
+ private _detectionsToday: number = 0;
14
+ private _movementDetectedCallback: Array<(pValue: boolean) => void> = [];
15
+ private static MOVEMENT_DETECTION: string = 'MOTION';
16
+ private initialized: boolean = false;
17
+ private fallBackTimeout: NodeJS.Timeout | undefined;
18
+
19
+ public get detectionsToday(): number {
20
+ return this._detectionsToday;
21
+ }
22
+
23
+ public set detectionsToday(pVal: number) {
24
+ const oldVal: number = this._detectionsToday;
25
+ this._detectionsToday = pVal;
26
+ Persist.persistTodayCount(this, pVal, oldVal);
27
+ }
28
+
29
+ public constructor(pInfo: DeviceInfo) {
30
+ super(pInfo, HmIpDeviceType.HmIpBewegung);
31
+ Persist.getCount(this).then((todayCount: CountToday) => {
32
+ this.detectionsToday = todayCount.counter;
33
+ ServerLogService.writeLog(
34
+ LogLevel.Debug,
35
+ `Bewegungscounter "${this.info.customName}" vorinitialisiert mit ${this.detectionsToday}`,
36
+ );
37
+ this.initialized = true;
38
+ });
39
+ }
40
+
41
+ public addMovementCallback(pCallback: (pValue: boolean) => void): void {
42
+ this._movementDetectedCallback.push(pCallback);
43
+ }
44
+
45
+ public update(idSplit: string[], state: ioBroker.State, initial: boolean = false): void {
46
+ ServerLogService.writeLog(
47
+ LogLevel.Trace,
48
+ `Bewegungs Update: JSON: ${JSON.stringify(state)}ID: ${idSplit.join('.')}`,
49
+ );
50
+ super.update(idSplit, state, initial, true);
51
+
52
+ if (idSplit[3] !== '3') {
53
+ // Nur die Infos in Kanal 1 sind relevant
54
+ return;
55
+ }
56
+
57
+ switch (idSplit[4]) {
58
+ case HmIpBewegung.MOVEMENT_DETECTION:
59
+ this.updateMovement(state.val as boolean);
60
+ break;
61
+ }
62
+ }
63
+
64
+ public updateMovement(pVal: boolean): void {
65
+ if (!this.initialized && pVal) {
66
+ ServerLogService.writeLog(
67
+ LogLevel.Trace,
68
+ `Bewegung für "${this.info.customName}" erkannt aber die Initialisierung aus der DB ist noch nicht erfolgt --> verzögern`,
69
+ );
70
+ Utils.guardedTimeout(
71
+ () => {
72
+ this.updateMovement(pVal);
73
+ },
74
+ 1000,
75
+ this,
76
+ );
77
+ return;
78
+ }
79
+ if (pVal === this.movementDetected) {
80
+ ServerLogService.writeLog(
81
+ LogLevel.Debug,
82
+ `Überspringe Bewegung für "${this.info.customName}" da bereits der Wert ${pVal} vorliegt`,
83
+ );
84
+ if (pVal) {
85
+ this.resetFallbackTimeout();
86
+ this.startFallbackTimeout();
87
+ }
88
+ return;
89
+ }
90
+
91
+ this.resetFallbackTimeout();
92
+ this.movementDetected = pVal;
93
+ ServerLogService.writeLog(LogLevel.Debug, `Neuer Bewegunsstatus Wert für "${this.info.customName}": ${pVal}`);
94
+ if (pVal) {
95
+ this.startFallbackTimeout();
96
+ this.detectionsToday++;
97
+ ServerLogService.writeLog(
98
+ LogLevel.Trace,
99
+ `Dies ist die ${this.detectionsToday} Bewegung für "${this.info.customName}"`,
100
+ );
101
+ }
102
+
103
+ for (const c of this._movementDetectedCallback) {
104
+ c(pVal);
105
+ }
106
+ }
107
+
108
+ private resetFallbackTimeout(): void {
109
+ if (this.fallBackTimeout) {
110
+ ServerLogService.writeLog(LogLevel.Trace, `Fallback Timeout für "${this.info.customName}" zurücksetzen`);
111
+ clearTimeout(this.fallBackTimeout);
112
+ }
113
+ }
114
+
115
+ private startFallbackTimeout(): void {
116
+ this.fallBackTimeout = Utils.guardedTimeout(
117
+ () => {
118
+ ServerLogService.writeLog(LogLevel.Debug, `Benötige Fallback Bewegungs Reset für "${this.info.customName}"`);
119
+ this.fallBackTimeout = undefined;
120
+ this.updateMovement(false);
121
+ },
122
+ 270000,
123
+ this,
124
+ );
125
+ }
126
+ }
@@ -0,0 +1,90 @@
1
+ import { DeviceInfo } from '../DeviceInfo';
2
+ import { HmIpDeviceType } from './hmIpDeviceType';
3
+ import { LogLevel } from '../../../models/logLevel';
4
+ import { HmIpAddDeviceItem, HmIpRoomSettings } from '../../../models/rooms/RoomSettings/hmIPRoomSettings';
5
+ import { ServerLogService } from '../../services/log-service';
6
+ import { ioBrokerBaseDevice } from '../iIoBrokerDevice';
7
+ import { RoomBase } from '../../../models/rooms/RoomBase';
8
+
9
+ export class HmIPDevice extends ioBrokerBaseDevice {
10
+ public static roomSettings: { [id: string]: HmIpRoomSettings } = {};
11
+ public lowBattery: boolean = false;
12
+ public deviceType: HmIpDeviceType;
13
+ public room: RoomBase | undefined = undefined;
14
+
15
+ public static addRoom(shortName: string, settings: HmIpRoomSettings): void {
16
+ if (this.roomSettings[shortName] !== undefined) {
17
+ ServerLogService.writeLog(
18
+ LogLevel.Alert,
19
+ `Es gibt bereits ein Registrat für HmIpRoomsettings für den Raumnamen "${shortName}"`,
20
+ );
21
+ return;
22
+ }
23
+ this.roomSettings[shortName] = settings;
24
+ }
25
+
26
+ public static checkMissing(): void {
27
+ for (const rName in this.roomSettings) {
28
+ this.roomSettings[rName].checkMissing();
29
+ }
30
+ }
31
+
32
+ public constructor(pInfo: DeviceInfo, pType: HmIpDeviceType) {
33
+ super(pInfo);
34
+ this.deviceType = pType;
35
+ this.addToCorrectRoom();
36
+ }
37
+
38
+ protected addToCorrectRoom(): void {
39
+ const settings: HmIpRoomSettings | undefined = HmIPDevice.roomSettings[this.info.room];
40
+ if (settings !== undefined) {
41
+ if (settings.devices[this.deviceType] === undefined) {
42
+ ServerLogService.missingRoomHandling(settings.RoomName, this.deviceType);
43
+ return;
44
+ }
45
+ const deviceSettings: HmIpAddDeviceItem | undefined =
46
+ settings.devices[this.deviceType][this.info.deviceRoomIndex];
47
+ if (deviceSettings === undefined) {
48
+ ServerLogService.missingRoomIndexHandling(settings.RoomName, this.info.deviceRoomIndex, this.deviceType);
49
+ return;
50
+ }
51
+
52
+ if (deviceSettings.customName !== undefined) {
53
+ this.info.customName = deviceSettings.customName;
54
+ }
55
+ deviceSettings.setID(this.info.devID);
56
+ deviceSettings.added = true;
57
+ ServerLogService.addedDeviceToRoom(settings.RoomName, this.deviceType, this.info.deviceRoomIndex);
58
+ return;
59
+ }
60
+ switch (this.info.room) {
61
+ default:
62
+ ServerLogService.writeLog(LogLevel.Warn, `${this.info.room} is noch kein bekannter Raum`);
63
+ }
64
+ }
65
+
66
+ public update(idSplit: string[], state: ioBroker.State, initial: boolean = false, pOverride: boolean = false): void {
67
+ if (!pOverride) {
68
+ ServerLogService.writeLog(
69
+ LogLevel.Trace,
70
+ `Keine Update Überschreibung für "${this.info.customName}":\n\tID: ${idSplit.join(
71
+ '.',
72
+ )}\n\tData: ${JSON.stringify(state)}`,
73
+ );
74
+ }
75
+
76
+ if (idSplit[3] !== '0') {
77
+ // Dies ist etwas Gerätespezifisches
78
+ return;
79
+ }
80
+
81
+ switch (idSplit[4]) {
82
+ case 'LOW_BAT':
83
+ const newBatLowVal: boolean = state.val as boolean;
84
+ if (newBatLowVal) {
85
+ ServerLogService.writeLog(LogLevel.Alert, `!!BATTERIE FAST LEER!! "${this.info.customName}"`);
86
+ }
87
+ break;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,14 @@
1
+ export enum HmIpDeviceType {
2
+ unknown = 0,
3
+ HmIpLampe = 1,
4
+ HmIpTaster = 2,
5
+ HmIpRoll = 3,
6
+ HmIpTherm = 4,
7
+ HmIpPraezenz = 5,
8
+ HmIpGriff = 6,
9
+ HmIpWippe = 7,
10
+ HmIpHeizung = 8,
11
+ HmIpTuer = 9,
12
+ HmIpHeizgruppe = 10,
13
+ HmIpBewegung = 11,
14
+ }