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,91 @@
1
+ import { Persist } from '../services/dbo/persist';
2
+ import { Devices } from './devices';
3
+ import { HmIpDeviceType } from './hmIPDevices/hmIpDeviceType';
4
+ import { HmIpHeizgruppe } from './hmIPDevices/hmIpHeizgruppe';
5
+ import { HmIpHeizung } from './hmIPDevices/hmIpHeizung';
6
+ import { TemperaturDataPoint } from '/models/persistence/temperaturDataPoint';
7
+
8
+ export class Heizgruppen {
9
+ public static getInfo(): string {
10
+ const gruppen: HmIpHeizgruppe[] = Heizgruppen.getAllGruppen();
11
+ gruppen.sort((a, b): number => {
12
+ return a.info.customName.localeCompare(b.info.customName);
13
+ });
14
+
15
+ const response: string[] = [`Dies sind die aktuellen Informationen der Heizungen:`];
16
+ response.push(`Name\t\tLuft Feuchtigkeit\t\tAktuelle Temperatur\t\tSoll Temperatur\t\tVentilstellung`);
17
+ for (const g of gruppen) {
18
+ response.push(
19
+ `${g.info.customName}:\t\t${g.humidity}%\t\t${g.sTemperatur}\t\t${g.desiredTemperatur}°C\t\t${g.sLevel}`,
20
+ );
21
+ }
22
+ return response.join('\n');
23
+ }
24
+
25
+ public static async getSpecificInfo(pText: string | undefined): Promise<string> {
26
+ if (pText === undefined || !pText.includes('"')) {
27
+ return `Bitte übergeben Sie eine Heizgruppe innerhalb von "". z.B. "EG Flur HeizGr"`;
28
+ }
29
+ const searchText = pText.split('"')[1];
30
+ const group: HmIpHeizgruppe | undefined = this.getSpecificGroup(searchText);
31
+
32
+ if (group === undefined) {
33
+ return `"${searchText}" ist keine gültige Heizgruppe, im Folgenden ist eine Liste aller gültigen Heizgruppen:\n${this.getInfo()}`;
34
+ }
35
+
36
+ const results: TemperaturDataPoint[] = await Persist.readTemperaturDataPoint(group, 20);
37
+ const response: string[] = [`Dies sind die letzten 20 Messpunkte der Heizgruppe:`];
38
+ response.push(`Zeitpunkt\t\tIst-Temperatur\t\tSoll-Temperatur\t\tVentilstellung`);
39
+ for (const r of results) {
40
+ response.push(
41
+ `${r.date.toLocaleTimeString('de-DE')}:\t\t${r.istTemperatur}°C\t\t${r.sollTemperatur}°C\t\t${r.level}%`,
42
+ );
43
+ }
44
+ return response.join('\n');
45
+ }
46
+
47
+ public static getProblems(): string {
48
+ const groups: HmIpHeizgruppe[] = this.getAllGruppen();
49
+
50
+ const response: string[] = [`Dies sind die bestehenden Differenzen:`];
51
+ response.push(`Raumname\t\tIst-Temperatur\t\tGerät`);
52
+ for (const g of groups) {
53
+ const heizungen: HmIpHeizung[] = g.getBelongingHeizungen();
54
+ const tempProblem: string[] = [`${g.info.room}\t\t${g.iTemperatur}°C\t\t${g.info.customName}`];
55
+ let print = false;
56
+ for (const h of heizungen) {
57
+ if (h.iTemperatur !== g.iTemperatur) {
58
+ print = true;
59
+ }
60
+ tempProblem.push(`${h.info.room}\t\t${h.iTemperatur}°C\t\t${h.info.customName}`);
61
+ }
62
+ if (print) {
63
+ response.push(tempProblem.join('\n'));
64
+ response.push(' ');
65
+ }
66
+ }
67
+ return response.join('\n');
68
+ }
69
+
70
+ public static getAllGruppen(): HmIpHeizgruppe[] {
71
+ const gruppen: HmIpHeizgruppe[] = [];
72
+ for (const dID in Devices.hmIP) {
73
+ const d = Devices.hmIP[dID];
74
+ if (d.deviceType === HmIpDeviceType.HmIpHeizgruppe) {
75
+ gruppen.push(d as HmIpHeizgruppe);
76
+ }
77
+ }
78
+ return gruppen;
79
+ }
80
+
81
+ public static getSpecificGroup(name: string): HmIpHeizgruppe | undefined {
82
+ for (const dID in Devices.hmIP) {
83
+ const d = Devices.hmIP[dID];
84
+ if (d.deviceType === HmIpDeviceType.HmIpHeizgruppe && d.info.customName === name) {
85
+ return d as HmIpHeizgruppe;
86
+ }
87
+ }
88
+
89
+ return undefined;
90
+ }
91
+ }
@@ -0,0 +1,48 @@
1
+ import { Devices } from './devices';
2
+ import { HmIpDeviceType } from './hmIPDevices/hmIpDeviceType';
3
+ import { HmIpRoll } from './hmIPDevices/hmIpRoll';
4
+ import { RoomBase } from '/models/rooms/RoomBase';
5
+
6
+ export class Rolladen {
7
+ public static getRolladenPosition(): string {
8
+ const rollos: HmIpRoll[] = Rolladen.getAllRollos();
9
+ rollos.sort((a, b): number => {
10
+ return b.currentLevel - a.currentLevel;
11
+ });
12
+
13
+ const response: string[] = [`Dies sind die aktuellen Rollo Positionen:`];
14
+ for (const r of rollos) {
15
+ response.push(`${r.currentLevel}% Rollo: "${r.info.customName}" Gewünschte Position: ${r.desiredFensterLevel}`);
16
+ }
17
+ response.push(`\nDie nächsten Zeiten zum Hochfahren:`);
18
+ const down: string[] = [`\nDie nächsten Zeiten zum Runterfahren:`];
19
+ const rooms: RoomBase[] = RoomBase.allRooms;
20
+ for (const r of rooms) {
21
+ for (const f of r.FensterGroup.fenster) {
22
+ if (f.rollo) {
23
+ response.push(
24
+ `Rollo: "${f.rollo.info.customName}"\t${
25
+ f.noRolloOnSunrise ? 'Hochfahren inaktiv' : r.sonnenAufgangCallback?.nextToDo?.toLocaleTimeString()
26
+ }`,
27
+ );
28
+ down.push(
29
+ `Rollo: "${f.rollo.info.customName}"\t${r.sonnenUntergangCallback?.nextToDo?.toLocaleTimeString()}`,
30
+ );
31
+ }
32
+ }
33
+ }
34
+ response.push(down.join('\n'));
35
+ return response.join('\n');
36
+ }
37
+
38
+ public static getAllRollos(): HmIpRoll[] {
39
+ const rollos: HmIpRoll[] = [];
40
+ for (const dID in Devices.hmIP) {
41
+ const d = Devices.hmIP[dID];
42
+ if (d.deviceType === HmIpDeviceType.HmIpRoll) {
43
+ rollos.push(d as HmIpRoll);
44
+ }
45
+ }
46
+ return rollos;
47
+ }
48
+ }
@@ -0,0 +1,72 @@
1
+ import { ServerLogService } from '../services/log-service';
2
+ import { Devices } from './devices';
3
+ import { HmIPDevice } from './hmIPDevices/hmIpDevice';
4
+ import { IDeviceUpdater } from './iDeviceUpdater';
5
+ import { ZigbeeDevice } from './zigbee/zigbeeDevice';
6
+ import { LogLevel } from '/models/logLevel';
7
+
8
+ export class DeviceUpdater implements IDeviceUpdater {
9
+ private static IDENTIFIER_HOMEMATIC: string = 'hm-rpc';
10
+ private static IDENTIFIER_ZIGBEE: string = 'zigbee';
11
+ public devices: Devices;
12
+
13
+ constructor(pDevices: Devices) {
14
+ this.devices = pDevices;
15
+ }
16
+
17
+ public updateObject(pId: string, pObj: ioBroker.Object): void {
18
+ const idSplit: string[] = pId.split('.');
19
+ if (idSplit.length < 2) return;
20
+
21
+ if (idSplit[0] === DeviceUpdater.IDENTIFIER_HOMEMATIC) {
22
+ console.log(`Neuer Wert in HomematicIP für ${pId}: ${JSON.stringify(pObj)}`);
23
+ }
24
+ }
25
+
26
+ public updateState(id: string, state: ioBroker.State, initial: boolean = false): void {
27
+ if (state === null) {
28
+ // Ignore null states
29
+ return;
30
+ }
31
+ const idSplit: string[] = id.split('.');
32
+ if (idSplit.length < 2) return;
33
+
34
+ if (idSplit[0] === DeviceUpdater.IDENTIFIER_HOMEMATIC) {
35
+ try {
36
+ this.updateHomeMaticDevice(idSplit, state, initial);
37
+ } catch (e: any) {
38
+ ServerLogService.writeLog(
39
+ LogLevel.Alert,
40
+ `deviceUpdater.updateState('${id}', '${state}'): Error occured updating Device: ${e} \n ${e.stack}`,
41
+ );
42
+ }
43
+ } else if (idSplit[0] === DeviceUpdater.IDENTIFIER_ZIGBEE) {
44
+ try {
45
+ this.updateZigbeeDevice(idSplit, state, initial);
46
+ } catch (e: any) {
47
+ ServerLogService.writeLog(
48
+ LogLevel.Alert,
49
+ `deviceUpdater.updateState('${id}', '${state}'): Error occured updating Device: ${e} \n ${e.stack}`,
50
+ );
51
+ }
52
+ } else {
53
+ ServerLogService.writeLog(LogLevel.DeepTrace, `unbekannter Identifier: "${idSplit[0]}"`);
54
+ }
55
+ }
56
+
57
+ private updateHomeMaticDevice(idSplit: string[], state: ioBroker.State, initial: boolean = false) {
58
+ const device: undefined | HmIPDevice = Devices.hmIP[idSplit[2]];
59
+ if (typeof device === 'undefined') {
60
+ return;
61
+ }
62
+ device.update(idSplit, state, initial);
63
+ }
64
+
65
+ private updateZigbeeDevice(idSplit: string[], state: ioBroker.State, initial: boolean = false) {
66
+ const device: undefined | ZigbeeDevice = Devices.Zigbee[idSplit[2]];
67
+ if (typeof device === 'undefined') {
68
+ return;
69
+ }
70
+ device.update(idSplit, state, initial);
71
+ }
72
+ }
@@ -0,0 +1,189 @@
1
+ import { HmIpDeviceType } from './hmIPDevices/hmIpDeviceType';
2
+ import { ZigbeeDeviceType } from './zigbee/zigbeeDeviceType';
3
+ import { IOBrokerConnection } from '../ioBroker/connection';
4
+ import { ServerLogService } from '../services/log-service';
5
+ import { HmIPDevice } from './hmIPDevices/hmIpDevice';
6
+ import { ZigbeeDevice } from './zigbee/zigbeeDevice';
7
+ import { HmIpGriff } from './hmIPDevices/hmIpGriff';
8
+ import { HmIpHeizung } from './hmIPDevices/hmIpHeizung';
9
+ import { DeviceInfo } from './DeviceInfo';
10
+ import { HmIpLampe } from './hmIPDevices/hmIpLampe';
11
+ import { HmIpPraezenz } from './hmIPDevices/hmIpPraezenz';
12
+ import { HmIpRoll } from './hmIPDevices/hmIpRoll';
13
+ import { HmIpTaster } from './hmIPDevices/hmIpTaster';
14
+ import { HmIpTherm } from './hmIPDevices/hmIpTherm';
15
+ import { HmIpTuer } from './hmIPDevices/hmIpTuer';
16
+ import { HmIpWippe } from './hmIPDevices/hmIpWippe';
17
+ import { deviceConfig } from '/models/deviceConfig';
18
+ import { LogLevel } from '/models/logLevel';
19
+ import { HmIpHeizgruppe } from './hmIPDevices/hmIpHeizgruppe';
20
+ import { HmIpBewegung } from './hmIPDevices/hmIpBewegung';
21
+ import { ZigbeeIkeaSteckdose } from './zigbee/zigbeeIkeaSteckdose';
22
+ import { ZigbeeIlluLedRGBCCT } from './zigbee/zigbeeIlluLedRGBCCT';
23
+ import { ZigbeeAquaraVibra } from './zigbee/zigbeeAquaraVibra';
24
+ import { ZigbeeIlluDimmer } from './zigbee/zigbeeIlluDimmer';
25
+ import { ZigbeeHeimanSmoke } from '/server/devices/zigbee/zigbeeHeimanSmoke';
26
+ import { ZigbeeAquaraWater } from '/server/devices/zigbee/zigbeeAquaraWater';
27
+ import { ZigbeeBlitzShp } from '/server/devices/zigbee/zigbeeBlitzShp';
28
+ import { ZigbeeIlluLampe } from '/server/devices/zigbee/zigbeeIlluLampe';
29
+ import { ZigbeeIlluActuator } from '/server/devices/zigbee/zigbeeIlluActuator';
30
+ import { iRoomImportEnforcer } from '/models/rooms/iRoomImportEnforcer';
31
+
32
+ export class Devices {
33
+ public static hmIP: { [id: string]: HmIPDevice } = {};
34
+ public static Zigbee: { [id: string]: ZigbeeDevice } = {};
35
+
36
+ public constructor(pDeviceData: { [id: string]: deviceConfig }, pRoomImportEnforcer: iRoomImportEnforcer) {
37
+ // This forces import of rooms at correct timing, to allow devices to land in proper rooms.
38
+ pRoomImportEnforcer.addRoomConstructor();
39
+
40
+ for (const cID in pDeviceData) {
41
+ const cDevConf: deviceConfig = pDeviceData[cID];
42
+ if (
43
+ !cDevConf.common ||
44
+ !cDevConf.common.name ||
45
+ typeof cDevConf.common.name === 'object' ||
46
+ !cDevConf.type ||
47
+ cDevConf.type === 'channel'
48
+ ) {
49
+ continue;
50
+ }
51
+
52
+ const cName: string = cDevConf.common.name;
53
+
54
+ if (cName.indexOf('00-HmIP') === 0) {
55
+ this.processHMIPDevice(cDevConf);
56
+ } else if (cName.indexOf('00-Zigbee') === 0) {
57
+ this.processZigbeeDevice(cDevConf);
58
+ }
59
+ }
60
+
61
+ HmIPDevice.checkMissing();
62
+ ZigbeeDevice.checkMissing();
63
+ }
64
+
65
+ public static addIoConnection(pIoConnection: IOBrokerConnection): void {
66
+ for (const id in Devices.hmIP) {
67
+ Devices.hmIP[id].ioConn = pIoConnection;
68
+ }
69
+
70
+ for (const id in Devices.Zigbee) {
71
+ Devices.Zigbee[id].ioConn = pIoConnection;
72
+ }
73
+ }
74
+
75
+ public static midnightReset(): void {
76
+ // Nothing yet
77
+ }
78
+
79
+ public static resetPraesenzCount(): void {
80
+ ServerLogService.writeLog(LogLevel.Info, `3 Uhr Reset der Präsenzmelder`);
81
+ for (const dID in Devices.hmIP) {
82
+ const d = Devices.hmIP[dID];
83
+ if (d.deviceType === HmIpDeviceType.HmIpPraezenz) {
84
+ ServerLogService.writeLog(LogLevel.Debug, `2 Uhr Reset der Tages Detektionen von ${d.info.customName}`);
85
+ (d as HmIpPraezenz).detectionsToday = 0;
86
+ } else if (d.deviceType === HmIpDeviceType.HmIpBewegung) {
87
+ ServerLogService.writeLog(LogLevel.Debug, `2 Uhr Reset der Tages Detektionen von ${d.info.customName}`);
88
+ (d as HmIpBewegung).detectionsToday = 0;
89
+ }
90
+ }
91
+ }
92
+
93
+ private processZigbeeDevice(cDevConf: deviceConfig) {
94
+ const zigbeeInfo: DeviceInfo = new DeviceInfo(cDevConf);
95
+
96
+ if (typeof Devices.Zigbee[zigbeeInfo.devID] !== 'undefined') {
97
+ return;
98
+ }
99
+
100
+ ServerLogService.writeLog(
101
+ LogLevel.Trace,
102
+ `${zigbeeInfo.devID} with Type "${zigbeeInfo.deviceType}" doesn't exists --> create it`,
103
+ );
104
+
105
+ switch (zigbeeInfo.deviceType) {
106
+ case 'AquaraVibra':
107
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeAquaraVibra(zigbeeInfo);
108
+ break;
109
+ case 'IkeaStecker':
110
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIkeaSteckdose(zigbeeInfo);
111
+ break;
112
+ case 'LedRGBCCT':
113
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIlluLedRGBCCT(zigbeeInfo);
114
+ break;
115
+ case 'IlluDimmer':
116
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIlluDimmer(zigbeeInfo);
117
+ break;
118
+ case 'HeimanSmoke':
119
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeHeimanSmoke(zigbeeInfo);
120
+ break;
121
+ case 'AquaraWater':
122
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeAquaraWater(zigbeeInfo);
123
+ break;
124
+ case 'BlitzShp':
125
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeBlitzShp(zigbeeInfo);
126
+ break;
127
+ case 'IlluLampe':
128
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIlluLampe(zigbeeInfo);
129
+ break;
130
+ case 'IlluActuator':
131
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeIlluActuator(zigbeeInfo);
132
+ break;
133
+ default:
134
+ ServerLogService.writeLog(LogLevel.Warn, `No zigbee Device Type for ${zigbeeInfo.deviceType} defined`);
135
+ Devices.Zigbee[zigbeeInfo.devID] = new ZigbeeDevice(zigbeeInfo, ZigbeeDeviceType.unknown);
136
+ }
137
+ }
138
+
139
+ private processHMIPDevice(cDevConf: deviceConfig) {
140
+ const hmIPInfo: DeviceInfo = new DeviceInfo(cDevConf);
141
+
142
+ if (typeof Devices.hmIP[hmIPInfo.devID] !== 'undefined') {
143
+ return;
144
+ }
145
+ ServerLogService.writeLog(
146
+ LogLevel.Trace,
147
+ `${hmIPInfo.devID} with Type "${hmIPInfo.deviceType}" doesn't exists --> create it`,
148
+ );
149
+ switch (hmIPInfo.deviceType) {
150
+ case 'Lampe':
151
+ Devices.hmIP[hmIPInfo.devID] = new HmIpLampe(hmIPInfo);
152
+ break;
153
+ case 'Roll':
154
+ case 'Broll':
155
+ Devices.hmIP[hmIPInfo.devID] = new HmIpRoll(hmIPInfo);
156
+ break;
157
+ case 'Beweg':
158
+ Devices.hmIP[hmIPInfo.devID] = new HmIpBewegung(hmIPInfo);
159
+ break;
160
+ case 'Taster':
161
+ Devices.hmIP[hmIPInfo.devID] = new HmIpTaster(hmIPInfo);
162
+ break;
163
+ case 'Wippe':
164
+ Devices.hmIP[hmIPInfo.devID] = new HmIpWippe(hmIPInfo);
165
+ break;
166
+ case 'Praezenz':
167
+ Devices.hmIP[hmIPInfo.devID] = new HmIpPraezenz(hmIPInfo);
168
+ break;
169
+ case 'Griff':
170
+ Devices.hmIP[hmIPInfo.devID] = new HmIpGriff(hmIPInfo);
171
+ break;
172
+ case 'Thermostat':
173
+ Devices.hmIP[hmIPInfo.devID] = new HmIpTherm(hmIPInfo);
174
+ break;
175
+ case 'Heizung':
176
+ Devices.hmIP[hmIPInfo.devID] = new HmIpHeizung(hmIPInfo);
177
+ break;
178
+ case 'Tuer':
179
+ Devices.hmIP[hmIPInfo.devID] = new HmIpTuer(hmIPInfo);
180
+ break;
181
+ case 'HeizGr':
182
+ Devices.hmIP[hmIPInfo.devID] = new HmIpHeizgruppe(hmIPInfo);
183
+ break;
184
+ default:
185
+ ServerLogService.writeLog(LogLevel.Warn, `No HmIP Device Type for ${hmIPInfo.deviceType} defined`);
186
+ Devices.hmIP[hmIPInfo.devID] = new HmIPDevice(hmIPInfo, HmIpDeviceType.unknown);
187
+ }
188
+ }
189
+ }
@@ -0,0 +1,175 @@
1
+ import { Fenster } from '../hmIPDevices/Fenster';
2
+ import { FensterPosition } from '../hmIPDevices/FensterPosition';
3
+ import { ServerLogService } from '../../services/log-service';
4
+ import { LogLevel } from '../../../models/logLevel';
5
+ import { RoomBase } from '../../../models/rooms/RoomBase';
6
+ import { TimeCallback, TimeCallbackType } from '../../../models/timeCallback';
7
+ import { TimeCallbackService, TimeOfDay } from '../../services/time-callback-service';
8
+ import { Utils } from '../../services/utils/utils';
9
+ import { WeatherService } from '../../services/weather/weather-service';
10
+
11
+ export class FensterGroup {
12
+ public constructor(private _room: RoomBase, public fenster: Fenster[]) {
13
+ for (const f of [...fenster]) {
14
+ f.room = this._room;
15
+ }
16
+ }
17
+
18
+ public allRolloDown(initial: boolean = false, savePosition: boolean = false): void {
19
+ this.fenster.forEach((f) => {
20
+ if (savePosition) f.desiredPosition = 0;
21
+ if (f.rollo !== undefined) {
22
+ ServerLogService.writeLog(
23
+ LogLevel.Debug,
24
+ `Fahre das Rollo zum Sonnenuntergang ${initial ? '(ggf. nachträglich) ' : ''}für ${
25
+ f.rollo.info.customName
26
+ } runter`,
27
+ );
28
+ f.rollo.down(initial);
29
+ }
30
+ });
31
+ }
32
+
33
+ public allRolloUp(savePosition: boolean = false): void {
34
+ this.fenster.forEach((f) => {
35
+ if (f.rollo === undefined) {
36
+ return;
37
+ }
38
+
39
+ if (savePosition) {
40
+ f.desiredPosition = 100;
41
+ }
42
+ f.rollo.up(false);
43
+ });
44
+ }
45
+
46
+ public allRolloToLevel(level: number, savePosition: boolean = false): void {
47
+ this.fenster.forEach((f) => {
48
+ if (savePosition) {
49
+ f.desiredPosition = level;
50
+ }
51
+ if (f.rollo !== undefined) {
52
+ f.rollo.setLevel(level, false);
53
+ }
54
+ });
55
+ }
56
+
57
+ public initCallbacks(): void {
58
+ if (this._room.Einstellungen.sonnenAufgangRollos && this._room.Einstellungen.rolloOffset) {
59
+ ServerLogService.writeLog(LogLevel.Trace, `Sonnenaufgang TimeCallback für ${this._room.roomName} hinzufügen`);
60
+ this._room.sonnenAufgangCallback = new TimeCallback(
61
+ `${this._room.roomName} Sonnenaufgang Rollos`,
62
+ TimeCallbackType.Sunrise,
63
+ () => {
64
+ if (this._room.skipNextRolloUp) {
65
+ this._room.skipNextRolloUp = false;
66
+ return;
67
+ }
68
+ this.sunriseUp();
69
+ },
70
+ this._room.Einstellungen.rolloOffset.sunrise,
71
+ undefined,
72
+ undefined,
73
+ this._room.Einstellungen.rolloOffset,
74
+ );
75
+ if (!TimeCallbackService.darkOutsideOrNight(TimeCallbackService.dayType(this._room.Einstellungen.rolloOffset))) {
76
+ this.sunriseUp(true);
77
+ }
78
+ TimeCallbackService.addCallback(this._room.sonnenAufgangCallback);
79
+ }
80
+
81
+ if (this._room.Einstellungen.sonnenUntergangRollos && this._room.Einstellungen.rolloOffset) {
82
+ this._room.sonnenUntergangCallback = new TimeCallback(
83
+ `${this._room.roomName} Sonnenuntergang Rollo`,
84
+ TimeCallbackType.SunSet,
85
+ () => {
86
+ this.sunsetDown();
87
+ },
88
+ this._room.Einstellungen.rolloOffset.sunset,
89
+ );
90
+ if (TimeCallbackService.darkOutsideOrNight(TimeCallbackService.dayType(this._room.Einstellungen.rolloOffset))) {
91
+ Utils.guardedTimeout(
92
+ () => {
93
+ this.allRolloDown(true, true);
94
+ },
95
+ 60000,
96
+ this,
97
+ );
98
+ }
99
+ TimeCallbackService.addCallback(this._room.sonnenUntergangCallback);
100
+ }
101
+
102
+ if (this._room.Einstellungen.rolloHeatReduction) {
103
+ Utils.guardedInterval(this.setRolloByWeatherStatus, 15 * 60 * 1000, this, true);
104
+ Utils.guardedTimeout(this.setRolloByWeatherStatus, 2 * 60 * 1000, this);
105
+ }
106
+ }
107
+
108
+ private sunsetDown(): void {
109
+ this.allRolloToLevel(0, true);
110
+ if (this._room.PraesenzGroup.anyPresent() && this._room.Einstellungen.lampOffset) {
111
+ this._room.LampenGroup.switchTimeConditional(TimeCallbackService.dayType(this._room.Einstellungen.lampOffset));
112
+ }
113
+ }
114
+
115
+ public setRolloByWeatherStatus(): void {
116
+ const timeOfDay: TimeOfDay = TimeCallbackService.dayType(this._room.Einstellungen.rolloOffset);
117
+ const darkOutside: boolean = TimeCallbackService.darkOutsideOrNight(timeOfDay);
118
+ this.fenster.forEach((f) => {
119
+ if (!f.rollo) {
120
+ return;
121
+ }
122
+ if (darkOutside) {
123
+ f.restoreDesiredPosition();
124
+ return;
125
+ }
126
+ let desiredPos: number = f.desiredPosition;
127
+ if (desiredPos > 0) {
128
+ WeatherService.weatherRolloPosition(
129
+ desiredPos,
130
+ this._room.HeatGroup.desiredTemp,
131
+ this._room.HeatGroup.currentTemp,
132
+ );
133
+ }
134
+ if (f.griffeInPosition(FensterPosition.offen) > 0 && desiredPos < 100) {
135
+ return;
136
+ }
137
+ if (f.griffeInPosition(FensterPosition.kipp) > 0) {
138
+ desiredPos = Math.max(30, desiredPos);
139
+ }
140
+ if (f.rollo.currentLevel === desiredPos) {
141
+ // Rollo ist bereits auf der Zielposition
142
+ return;
143
+ }
144
+ f.rollo.setLevel(desiredPos, false, true);
145
+ });
146
+ }
147
+
148
+ public sunriseUp(initial: boolean = false): void {
149
+ this.fenster.forEach((f) => {
150
+ if (!f.noRolloOnSunrise && f.rollo) {
151
+ ServerLogService.writeLog(
152
+ LogLevel.Debug,
153
+ `Fahre das Rollo zum Sonnenaufgang ${initial ? '(ggf. nachträglich)' : ''}für ${
154
+ f.rollo.info.customName
155
+ } hoch`,
156
+ );
157
+ f.setDesiredPosition(100);
158
+ }
159
+ });
160
+ }
161
+
162
+ public restoreRolloPosition(recalc: boolean = false): void {
163
+ if (!recalc) {
164
+ this.fenster.forEach((f) => {
165
+ f.restoreDesiredPosition();
166
+ });
167
+ return;
168
+ }
169
+ if (!TimeCallbackService.darkOutsideOrNight(TimeCallbackService.dayType(this._room.Einstellungen.rolloOffset))) {
170
+ this.sunriseUp(true);
171
+ } else {
172
+ this.sunsetDown();
173
+ }
174
+ }
175
+ }
@@ -0,0 +1,32 @@
1
+ import { RoomBase } from '../../../models/rooms/RoomBase';
2
+ import { HmIpHeizgruppe } from '../hmIPDevices/hmIpHeizgruppe';
3
+
4
+ export class HeatGroup {
5
+ public get currentTemp(): number {
6
+ if (this.heaters.length === 0) {
7
+ return -99;
8
+ }
9
+ let value: number = 0;
10
+ for (const h of this.heaters) {
11
+ value += h.iTemperatur;
12
+ }
13
+ return Math.round((value / this.heaters.length) * 10) / 10;
14
+ }
15
+
16
+ public get desiredTemp(): number {
17
+ if (this.heaters.length === 0) {
18
+ return -99;
19
+ }
20
+ let value: number = 0;
21
+ for (const h of this.heaters) {
22
+ value += h.desiredTemperatur;
23
+ }
24
+ return Math.round((value / this.heaters.length) * 10) / 10;
25
+ }
26
+
27
+ public constructor(private _room: RoomBase, public heaters: HmIpHeizgruppe[]) {
28
+ for (const h of [...heaters]) {
29
+ h.room = this._room;
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,88 @@
1
+ import { HmIpLampe } from '../hmIPDevices/hmIpLampe';
2
+ import { ZigbeeIkeaSteckdose } from '../zigbee/zigbeeIkeaSteckdose';
3
+ import { ZigbeeIlluDimmer } from '../zigbee/zigbeeIlluDimmer';
4
+ import { ZigbeeIlluLedRGBCCT } from '../zigbee/zigbeeIlluLedRGBCCT';
5
+ import { TimeCallbackService, TimeOfDay } from '../../services/time-callback-service';
6
+ import { RoomBase } from '../../../models/rooms/RoomBase';
7
+ import { ZigbeeIlluLampe } from '../zigbee/zigbeeIlluLampe';
8
+
9
+ export class LampenGroup {
10
+ public constructor(
11
+ private _room: RoomBase,
12
+ public Lampen: Array<HmIpLampe | ZigbeeIlluDimmer | ZigbeeIlluLampe>,
13
+ public Stecker: Array<ZigbeeIkeaSteckdose>,
14
+ public LED: Array<ZigbeeIlluLedRGBCCT> = [],
15
+ ) {
16
+ for (const lamp of [...Lampen, ...Stecker, ...LED]) {
17
+ lamp.room = this._room;
18
+ }
19
+ }
20
+
21
+ public switchAll(target: boolean, force: boolean = false): void {
22
+ this.setAllLampen(target, undefined, force);
23
+ this.setAllStecker(target, undefined, force);
24
+
25
+ this.LED.forEach((s) => {
26
+ s.setLight(target);
27
+ });
28
+ }
29
+
30
+ public switchTimeConditional(time: TimeOfDay): void {
31
+ const darkOutside: boolean = TimeCallbackService.darkOutsideOrNight(time);
32
+
33
+ let resultLampen = false;
34
+ let resultSteckdosen = false;
35
+ if (this.LED.length > 0) {
36
+ this.LED.forEach((s) => {
37
+ s.setTimeBased(time);
38
+ });
39
+ } else if (this.Stecker.length > 0) {
40
+ resultSteckdosen = darkOutside;
41
+ } else {
42
+ resultLampen = darkOutside;
43
+ }
44
+
45
+ this.setAllLampen(resultLampen, time);
46
+ this.setAllStecker(resultSteckdosen, time);
47
+ }
48
+
49
+ public setAllLampen(pValue: boolean, time?: TimeOfDay, force: boolean = false): void {
50
+ if (this.Lampen?.length > 0) {
51
+ this.Lampen.forEach((s) => {
52
+ if (
53
+ !pValue ||
54
+ time === undefined ||
55
+ (time === TimeOfDay.Night && s.settings.nightOn) ||
56
+ (time === TimeOfDay.BeforeSunrise && s.settings.dawnOn) ||
57
+ (time === TimeOfDay.AfterSunset && s.settings.duskOn)
58
+ ) {
59
+ const timeout: number = pValue && force ? 30 * 60 * 1000 : -1;
60
+ s.setLight(pValue, timeout, force);
61
+ }
62
+ });
63
+ }
64
+ }
65
+
66
+ public setAllStecker(pValue: boolean, time?: TimeOfDay, force: boolean = false): void {
67
+ if (this.Stecker?.length > 0) {
68
+ this.Stecker.forEach((s) => {
69
+ if (
70
+ !pValue ||
71
+ time === undefined ||
72
+ (time === TimeOfDay.Night && s.settings.nightOn) ||
73
+ (time === TimeOfDay.BeforeSunrise && s.settings.dawnOn) ||
74
+ (time === TimeOfDay.AfterSunset && s.settings.duskOn)
75
+ ) {
76
+ const timeout: number = pValue && force ? 30 * 60 * 1000 : -1;
77
+ s.setStecker(pValue, timeout, force);
78
+ }
79
+ });
80
+ }
81
+ }
82
+
83
+ public setAllLED(pValue: boolean, brightness: number = -1, color: string = '', colortemp: number = -1): void {
84
+ this.LED.forEach((s) => {
85
+ s.setLight(pValue, brightness, color, colortemp);
86
+ });
87
+ }
88
+ }