hoffmation-base 1.0.49 → 1.0.52

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.
@@ -14,6 +14,7 @@ export declare abstract class IoBrokerBaseDevice implements iBaseDevice {
14
14
  };
15
15
  room: RoomBase | undefined;
16
16
  readonly deviceCapabilities: DeviceCapability[];
17
+ protected readonly individualStateCallbacks: Map<string, Array<(val: ioBroker.StateValue) => void>>;
17
18
  protected constructor(_info: IoBrokerDeviceInfo, deviceType: DeviceType);
18
19
  get id(): string;
19
20
  /**
@@ -33,6 +34,12 @@ export declare abstract class IoBrokerBaseDevice implements iBaseDevice {
33
34
  get ioConn(): IOBrokerConnection | undefined;
34
35
  static addRoom(shortName: string, settings: RoomDeviceAddingSettings): void;
35
36
  static checkMissing(): void;
37
+ /**
38
+ * Allows to react on the state change of a given state with the passed cb
39
+ * @param {string} stateName Last part of the id e.g. "available" not "zigbee.0.00158d00053d3e4b.available"
40
+ * @param {(val: ioBroker.StateValue) => void} cb Desired Callback Action, with passed ioBroker.StateValue
41
+ */
42
+ addIndividualStateCallback(stateName: string, cb: (val: ioBroker.StateValue) => void): void;
36
43
  /**
37
44
  * Returns whether a connection to ioBroker is established or not
38
45
  * @param showError If true, an error message will be written to the log if the connection is not established
@@ -10,6 +10,7 @@ class IoBrokerBaseDevice {
10
10
  this.deviceType = deviceType;
11
11
  this.room = undefined;
12
12
  this.deviceCapabilities = [];
13
+ this.individualStateCallbacks = new Map();
13
14
  this.addToCorrectRoom();
14
15
  }
15
16
  get id() {
@@ -52,6 +53,21 @@ class IoBrokerBaseDevice {
52
53
  this.roomAddingSettings[rName].checkMissing();
53
54
  }
54
55
  }
56
+ /**
57
+ * Allows to react on the state change of a given state with the passed cb
58
+ * @param {string} stateName Last part of the id e.g. "available" not "zigbee.0.00158d00053d3e4b.available"
59
+ * @param {(val: ioBroker.StateValue) => void} cb Desired Callback Action, with passed ioBroker.StateValue
60
+ */
61
+ addIndividualStateCallback(stateName, cb) {
62
+ let arr = this.individualStateCallbacks.get(stateName);
63
+ if (arr === undefined) {
64
+ arr = [cb];
65
+ }
66
+ else {
67
+ arr.push(cb);
68
+ }
69
+ this.individualStateCallbacks.set(stateName, arr);
70
+ }
55
71
  /**
56
72
  * Returns whether a connection to ioBroker is established or not
57
73
  * @param showError If true, an error message will be written to the log if the connection is not established
@@ -71,7 +87,7 @@ class IoBrokerBaseDevice {
71
87
  });
72
88
  }
73
89
  toJSON() {
74
- return services_1.Utils.jsonFilter(this);
90
+ return services_1.Utils.jsonFilter(this, ['individualStateCallbacks']);
75
91
  }
76
92
  addToCorrectRoom() {
77
93
  const settings = IoBrokerBaseDevice.roomAddingSettings[this.info.room];
@@ -2,7 +2,7 @@ import { HeaterSettings, TemperatureSettings } from '../../../models';
2
2
  import { iBaseDevice } from './iBaseDevice';
3
3
  export interface iHeater extends iBaseDevice {
4
4
  settings: HeaterSettings;
5
- readonly desiredTemperature: number;
5
+ desiredTemperature: number;
6
6
  readonly humidity: number;
7
7
  readonly iLevel: number;
8
8
  readonly iTemperature: number;
@@ -19,14 +19,19 @@ class HmIpBewegung extends hmIpDevice_1.HmIPDevice {
19
19
  this._currentIllumination = -1;
20
20
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.motionSensor);
21
21
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.illuminationSensor);
22
- (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
23
- this.detectionsToday = todayCount.counter;
24
- this.log(models_1.LogLevel.Debug, `Bewegungscounter vorinitialisiert mit ${this.detectionsToday}`);
22
+ if (!services_1.Utils.anyDboActive) {
25
23
  this.initialized = true;
26
- }).catch((err) => {
27
- var _a;
28
- this.log(models_1.LogLevel.Warn, `Failed to initialize Movement Counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
29
- });
24
+ }
25
+ else {
26
+ (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
27
+ this.detectionsToday = todayCount.counter;
28
+ this.log(models_1.LogLevel.Debug, `Bewegungscounter vorinitialisiert mit ${this.detectionsToday}`);
29
+ this.initialized = true;
30
+ }).catch((err) => {
31
+ var _a;
32
+ this.log(models_1.LogLevel.Warn, `Failed to initialize Movement Counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
33
+ });
34
+ }
30
35
  }
31
36
  get timeSinceLastMotion() {
32
37
  return Math.floor((services_1.Utils.nowMS() - this._lastMotionTime) / 1000);
@@ -4,6 +4,7 @@ import { DeviceType } from '../deviceType';
4
4
  import { IoBrokerDeviceInfo } from '../IoBrokerDeviceInfo';
5
5
  export declare class HmIPDevice extends IoBrokerBaseDevice {
6
6
  lowBattery: boolean;
7
+ stateMap: Map<string, ioBroker.StateValue>;
7
8
  constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
8
9
  update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
9
10
  }
@@ -7,6 +7,7 @@ class HmIPDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
7
7
  constructor(pInfo, pType) {
8
8
  super(pInfo, pType);
9
9
  this.lowBattery = false;
10
+ this.stateMap = new Map();
10
11
  }
11
12
  update(idSplit, state, initial = false, pOverride = false) {
12
13
  if (!pOverride) {
@@ -14,18 +15,22 @@ class HmIPDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
14
15
  this.log(models_1.LogLevel.DeepTrace, `Data: ${JSON.stringify(state)}`);
15
16
  }
16
17
  this.log(models_1.LogLevel.DeepTrace, `Base-Device Update for ${this.info.customName}("${idSplit.join('.')}", ${state}, ${initial}, ${pOverride})`);
17
- if (idSplit[3] !== '0') {
18
- // Dies ist etwas Gerätespezifisches
19
- return;
20
- }
21
- switch (idSplit[4]) {
22
- case 'LOW_BAT':
18
+ const combinedStateName = `${idSplit[3]}.${idSplit[4]}`;
19
+ switch (combinedStateName) {
20
+ case '0.LOW_BAT':
23
21
  const newBatLowVal = state.val;
24
22
  if (newBatLowVal) {
25
23
  this.log(models_1.LogLevel.Warn, `!!BATTERIE FAST LEER!!`);
26
24
  }
27
25
  break;
28
26
  }
27
+ this.stateMap.set(combinedStateName, state.val);
28
+ const individualCallbacks = this.individualStateCallbacks.get(combinedStateName);
29
+ if (individualCallbacks !== undefined) {
30
+ for (const cb of individualCallbacks) {
31
+ cb(state.val);
32
+ }
33
+ }
29
34
  }
30
35
  }
31
36
  exports.HmIPDevice = HmIPDevice;
@@ -21,14 +21,19 @@ class HmIpPraezenz extends hmIpDevice_1.HmIPDevice {
21
21
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.illuminationSensor);
22
22
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.batteryDriven);
23
23
  // this.presenceStateID = `${this.info.fullID}.1.${HmIpPraezenz.PRESENCE_DETECTION}`;
24
- (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
25
- this.detectionsToday = todayCount.counter;
26
- this.log(models_1.LogLevel.Debug, `Präsenzcounter vorinitialisiert mit ${this.detectionsToday}`);
24
+ if (!services_1.Utils.anyDboActive) {
27
25
  this.initialized = true;
28
- }).catch((err) => {
29
- var _a;
30
- this.log(models_1.LogLevel.Warn, `Failed to initialize Movement Counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
31
- });
26
+ }
27
+ else {
28
+ (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
29
+ this.detectionsToday = todayCount.counter;
30
+ this.log(models_1.LogLevel.Debug, `Präsenzcounter vorinitialisiert mit ${this.detectionsToday}`);
31
+ this.initialized = true;
32
+ }).catch((err) => {
33
+ var _a;
34
+ this.log(models_1.LogLevel.Warn, `Failed to initialize Movement Counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
35
+ });
36
+ }
32
37
  }
33
38
  get detectionsToday() {
34
39
  return this._detectionsToday;
@@ -6,6 +6,7 @@ export declare class ZigbeeDevice extends IoBrokerBaseDevice {
6
6
  available: boolean;
7
7
  linkQuality: number;
8
8
  voltage: string;
9
+ stateMap: Map<string, ioBroker.StateValue>;
9
10
  constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
10
11
  update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
11
12
  }
@@ -9,6 +9,7 @@ class ZigbeeDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
9
9
  this.available = false;
10
10
  this.linkQuality = 0;
11
11
  this.voltage = '';
12
+ this.stateMap = new Map();
12
13
  }
13
14
  update(idSplit, state, initial = false, pOverride = false) {
14
15
  this.log(models_1.LogLevel.DeepTrace, `Zigbee: ${initial ? 'Initiales ' : ''}Update: ID: ${idSplit.join('.')} JSON: ${JSON.stringify(state)}`);
@@ -32,6 +33,13 @@ class ZigbeeDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
32
33
  this.voltage = state.val.toString();
33
34
  break;
34
35
  }
36
+ this.stateMap.set(idSplit[3], state.val);
37
+ const individualCallbacks = this.individualStateCallbacks.get(idSplit[3]);
38
+ if (individualCallbacks !== undefined) {
39
+ for (const cb of individualCallbacks) {
40
+ cb(state.val);
41
+ }
42
+ }
35
43
  }
36
44
  }
37
45
  exports.ZigbeeDevice = ZigbeeDevice;
@@ -1,11 +1,13 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="iobroker" />
2
3
  import { ZigbeeDevice } from './zigbeeDevice';
3
- import { iHeater } from '../../baseDeviceInterfaces';
4
+ import { iBatteryDevice, iHeater } from '../../baseDeviceInterfaces';
4
5
  import { HeaterSettings, TemperatureSettings } from '../../../../models';
5
6
  import { DeviceType } from '../../deviceType';
6
7
  import { IoBrokerDeviceInfo } from '../../IoBrokerDeviceInfo';
7
- export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater {
8
+ export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater, iBatteryDevice {
8
9
  settings: HeaterSettings;
10
+ battery: number;
9
11
  protected _automaticPoints: {
10
12
  [name: string]: TemperatureSettings;
11
13
  };
@@ -34,5 +36,6 @@ export declare class ZigbeeHeater extends ZigbeeDevice implements iHeater {
34
36
  setAutomaticPoint(name: string, setting: TemperatureSettings): void;
35
37
  stopAutomaticCheck(): void;
36
38
  onTemperaturChange(newTemperatur: number): void;
39
+ update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
37
40
  private checkSeasonTurnOff;
38
41
  }
@@ -10,6 +10,7 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
10
10
  constructor(pInfo, pType) {
11
11
  super(pInfo, pType);
12
12
  this.settings = new models_1.HeaterSettings();
13
+ this.battery = -99;
13
14
  this._automaticPoints = {};
14
15
  this._initialSeasonCheckDone = false;
15
16
  this._level = 0;
@@ -20,6 +21,7 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
20
21
  this._humidity = 0;
21
22
  this._roomTemperatur = 0;
22
23
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.heater);
24
+ this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.batteryDriven);
23
25
  this._iAutomaticInterval = services_1.Utils.guardedInterval(this.checkAutomaticChange, 300000, this); // Alle 5 Minuten prüfen
24
26
  services_1.TimeCallbackService.addCallback(new models_1.TimeCallback(`${this.info.fullID} Season Check`, models_1.TimeCallbackType.TimeOfDay, () => {
25
27
  this.checkSeasonTurnOff();
@@ -66,7 +68,7 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
66
68
  this._roomTemperatur = val;
67
69
  }
68
70
  checkAutomaticChange() {
69
- var _a, _b, _c;
71
+ var _a, _b;
70
72
  if (!this._initialSeasonCheckDone) {
71
73
  this.checkSeasonTurnOff();
72
74
  }
@@ -82,9 +84,9 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
82
84
  }
83
85
  if (this._desiredTemperatur !== setting.temperature) {
84
86
  this.log(models_1.LogLevel.Debug, `Automatische Temperaturanpassung für ${this.info.customName} auf ${setting.temperature}°C`);
85
- this.desiredTemperature = (_b = setting.temperature) !== null && _b !== void 0 ? _b : this.settings.automaticFallBackTemperatur;
87
+ this.desiredTemperature = setting.temperature;
86
88
  }
87
- (_c = services_1.Utils.dbo) === null || _c === void 0 ? void 0 : _c.addTemperaturDataPoint(this);
89
+ (_b = services_1.Utils.dbo) === null || _b === void 0 ? void 0 : _b.addTemperaturDataPoint(this);
88
90
  }
89
91
  deleteAutomaticPoint(name) {
90
92
  if (this._automaticPoints[name] !== undefined)
@@ -102,6 +104,17 @@ class ZigbeeHeater extends zigbeeDevice_1.ZigbeeDevice {
102
104
  onTemperaturChange(newTemperatur) {
103
105
  this.roomTemperatur = newTemperatur;
104
106
  }
107
+ update(idSplit, state, initial = false, pOverride = false) {
108
+ switch (idSplit[3]) {
109
+ case 'battery':
110
+ this.battery = state.val;
111
+ if (this.battery < 20) {
112
+ this.log(models_1.LogLevel.Warn, `Das Zigbee Gerät hat unter 20% Batterie.`);
113
+ }
114
+ break;
115
+ }
116
+ super.update(idSplit, state, initial, pOverride);
117
+ }
105
118
  checkSeasonTurnOff() {
106
119
  const desiredState = services_1.Utils.beetweenDays(new Date(), this.settings.seasonTurnOffDay, this.settings.seasonTurnOnDay);
107
120
  if (desiredState !== this.seasonTurnOff || !this._initialSeasonCheckDone) {
@@ -19,14 +19,19 @@ class ZigbeeMotionSensor extends index_1.ZigbeeDevice {
19
19
  this._detectionsToday = 0;
20
20
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.motionSensor);
21
21
  this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.batteryDriven);
22
- (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
23
- this.detectionsToday = todayCount.counter;
24
- this.log(models_1.LogLevel.Debug, `Preinitialized movement counter with ${this.detectionsToday}`);
22
+ if (!services_1.Utils.anyDboActive) {
25
23
  this._initialized = true;
26
- }).catch((err) => {
27
- var _a;
28
- this.log(models_1.LogLevel.Warn, `Failed to initialize movement counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
29
- });
24
+ }
25
+ else {
26
+ (_a = services_1.Utils.dbo) === null || _a === void 0 ? void 0 : _a.getCount(this).then((todayCount) => {
27
+ this.detectionsToday = todayCount.counter;
28
+ this.log(models_1.LogLevel.Debug, `Preinitialized movement counter with ${this.detectionsToday}`);
29
+ this._initialized = true;
30
+ }).catch((err) => {
31
+ var _a;
32
+ this.log(models_1.LogLevel.Warn, `Failed to initialize movement counter, err ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
33
+ });
34
+ }
30
35
  }
31
36
  // Time since last motion in seconds
32
37
  get timeSinceLastMotion() {
@@ -23,17 +23,17 @@ values ('${room.roomName}',${room.settings.etage})
23
23
  addTemperaturDataPoint(heater) {
24
24
  log_service_1.ServerLogService.writeLog(models_1.LogLevel.Trace, `Persisting Temperatur Data for ${heater.info.customName}`);
25
25
  this.query(`
26
- insert into hoffmation_schema."TemperaturData" ("date", humidity, "istTemperatur", level, name, "sollTemperatur")
26
+ insert into hoffmation_schema."TemperaturData" ("date", "humidity", "istTemperatur", "level", "name", "sollTemperatur")
27
27
  values ('${new Date().toISOString()}',${heater.humidity},${heater.iTemperature},${heater.iLevel},'${heater.info.customName}',${heater.desiredTemperature});`);
28
28
  this.query(`
29
- insert into hoffmation_schema."HeatGroupCollection" ("date", humidity, "istTemperatur", level, name, "sollTemperatur")
29
+ insert into hoffmation_schema."HeatGroupCollection" ("date", "humidity", "istTemperatur", "level", "name", "sollTemperatur")
30
30
  values ('${new Date().toISOString()}',${heater.humidity},${heater.iTemperature},${heater.iLevel},'${heater.info.customName}',${heater.desiredTemperature})
31
31
  ON CONFLICT (name)
32
32
  DO UPDATE SET
33
33
  "date" = '${new Date().toISOString()}',
34
- humidity = ${heater.humidity},
34
+ "humidity" = ${heater.humidity},
35
35
  "istTemperatur" = ${heater.iTemperature},
36
- level = ${heater.iLevel},
36
+ "level" = ${heater.iLevel},
37
37
  "sollTemperatur" = ${heater.desiredTemperature}
38
38
  ;
39
39
  `);
@@ -246,6 +246,7 @@ values ('${new Date(calc.startMs).toISOString()}','${new Date(calc.endMs).toISOS
246
246
  })
247
247
  .catch((r) => {
248
248
  log_service_1.ServerLogService.writeLog(models_1.LogLevel.Warn, `Postgres Query failed: ${r}`);
249
+ log_service_1.ServerLogService.writeLog(models_1.LogLevel.Debug, `Query: ${query}`);
249
250
  resolve(null);
250
251
  });
251
252
  });
@@ -3,6 +3,7 @@ import { iPersist } from '../dbo';
3
3
  export declare const DAYMS: number;
4
4
  export declare class Utils {
5
5
  static dbo: iPersist | undefined;
6
+ static get anyDboActive(): boolean;
6
7
  static get timeTilMidnight(): number;
7
8
  static catchEm<T>(promise: Promise<T>): Promise<{
8
9
  reason: Error | null;
@@ -16,7 +17,7 @@ export declare class Utils {
16
17
  static guardedInterval(func: (...args: unknown[]) => void, time: number, thisContext?: unknown | undefined, fireImmediate?: boolean): NodeJS.Timeout;
17
18
  static nowString(): string;
18
19
  static guard<T>(object: T | undefined | null): T;
19
- static jsonFilter(object: object): Partial<object>;
20
+ static jsonFilter(object: object, additionalOmitKeys?: string[]): Partial<object>;
20
21
  static testInitializeServices(): void;
21
22
  static kWh(wattage: number, durationInMs: number): number;
22
23
  static round(number: number, digits: number): number;
@@ -11,6 +11,11 @@ const Translation_1 = require("../Translation");
11
11
  const settings_service_1 = require("../settings-service");
12
12
  exports.DAYMS = 24 * 60 * 60 * 1000;
13
13
  class Utils {
14
+ static get anyDboActive() {
15
+ var _a, _b;
16
+ return (((_a = settings_service_1.SettingsService.settings.persistence) === null || _a === void 0 ? void 0 : _a.mongo) !== undefined ||
17
+ ((_b = settings_service_1.SettingsService.settings.persistence) === null || _b === void 0 ? void 0 : _b.postgreSql) !== undefined);
18
+ }
14
19
  static get timeTilMidnight() {
15
20
  return new Date(Utils.nowMS() + exports.DAYMS).setHours(0, 0, 0, 0) - Utils.nowMS();
16
21
  }
@@ -75,8 +80,10 @@ class Utils {
75
80
  }
76
81
  return object;
77
82
  }
78
- static jsonFilter(object) {
79
- return this.deepOmit(object, ['timeout', 'interval', 'timeouts', 'callback']);
83
+ static jsonFilter(object, additionalOmitKeys = []) {
84
+ const keysToOmit = ['timeout', 'interval', 'timeouts', 'callback'];
85
+ keysToOmit.push(...additionalOmitKeys);
86
+ return this.deepOmit(object, keysToOmit);
80
87
  }
81
88
  static testInitializeServices() {
82
89
  log_service_1.ServerLogService.settings.logLevel = -1;