hoffmation-base 3.4.9 → 3.6.0

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 (35) hide show
  1. package/lib/api/api-service.d.ts +9 -12
  2. package/lib/api/api-service.js +13 -28
  3. package/lib/command/acPerformAutomaticCheckCommand.d.ts +18 -0
  4. package/lib/command/acPerformAutomaticCheckCommand.js +25 -0
  5. package/lib/command/acSetStateCommand.d.ts +34 -0
  6. package/lib/command/acSetStateCommand.js +40 -0
  7. package/lib/command/acWriteStateToDeviceCommand.d.ts +25 -0
  8. package/lib/command/acWriteStateToDeviceCommand.js +30 -0
  9. package/lib/command/excessEnergyConsumerSetStateCommand.d.ts +19 -0
  10. package/lib/command/excessEnergyConsumerSetStateCommand.js +26 -0
  11. package/lib/command/index.d.ts +4 -0
  12. package/lib/command/index.js +9 -1
  13. package/lib/devices/groups/heatGroup.d.ts +6 -3
  14. package/lib/devices/groups/heatGroup.js +19 -8
  15. package/lib/devices/groups/tasterGroup.js +5 -2
  16. package/lib/devices/jsObject/jsObjectEnergyManager.js +3 -4
  17. package/lib/devices/sharedFunctions/shutterUtils.js +7 -2
  18. package/lib/devices/tv/tvDevice.d.ts +2 -1
  19. package/lib/devices/tv/tvDevice.js +5 -1
  20. package/lib/devices/victron/victron-device.js +3 -4
  21. package/lib/devices/zigbee/zigbeeBlitzShp.d.ts +2 -3
  22. package/lib/devices/zigbee/zigbeeBlitzShp.js +5 -7
  23. package/lib/enums/commandType.d.ts +4 -0
  24. package/lib/enums/commandType.js +4 -0
  25. package/lib/interfaces/baseDevices/iAcDevice.d.ts +14 -4
  26. package/lib/interfaces/baseDevices/iExcessEnergyConsumer.d.ts +7 -6
  27. package/lib/interfaces/groups/iHeatGroup.d.ts +4 -3
  28. package/lib/services/ac/ac-device.d.ts +45 -13
  29. package/lib/services/ac/ac-device.js +97 -33
  30. package/lib/services/ac/daikin-service.d.ts +2 -1
  31. package/lib/services/ac/daikin-service.js +8 -13
  32. package/lib/services/ac/own-daikin-device.d.ts +4 -3
  33. package/lib/services/ac/own-daikin-device.js +6 -6
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  import { iAcSettings } from '../deviceSettings';
2
2
  import { iBaseDevice } from './iBaseDevice';
3
3
  import { AcMode } from '../../enums';
4
+ import { AcSetStateCommand, AcWriteStateToDeviceCommand } from '../../command';
4
5
  /**
5
6
  * Interface for normal air-conditioning devices
6
7
  *
7
8
  * For devices with {@link DeviceCapability.ac} capability.
8
- * TODO: Migrate to new Command-Based System
9
9
  * TODO: Extend from iActuator
10
10
  */
11
11
  export interface iAcDevice extends iBaseDevice {
@@ -48,21 +48,31 @@ export interface iAcDevice extends iBaseDevice {
48
48
  * @param writeToDevice - Whether to write the new mode to the device
49
49
  */
50
50
  setDesiredMode(mode: AcMode, writeToDevice: boolean): void;
51
+ /**
52
+ * Performs a power write, applying any automatic block the command carries
53
+ * @param c - The command to execute
54
+ */
55
+ writeStateToDevice(c: AcWriteStateToDeviceCommand): void;
51
56
  /**
52
57
  * Turns the air-conditioning device on without changing the settings
58
+ * @param c - The command to execute
53
59
  */
54
- turnOn(): void;
60
+ turnOn(c: AcWriteStateToDeviceCommand): void;
55
61
  /**
56
62
  * Turns the air-conditioning device off
63
+ * @param c - The command to execute
57
64
  */
58
- turnOff(): void;
65
+ turnOff(c: AcWriteStateToDeviceCommand): void;
59
66
  /**
60
67
  * Calculates the desired mode based on the current settings and the room temperature
61
68
  * @returns The desired mode
62
69
  */
63
70
  calculateDesiredMode(): AcMode;
64
71
  /**
72
+ * Sets the state of the air-conditioning device.
65
73
  *
74
+ * Single entry point for every state change, so each one is recorded in the command log.
75
+ * @param c - The command to execute
66
76
  */
67
- setState(desiredMode: AcMode, desiredTemperature: number | undefined, forceTime: number): void;
77
+ setAcState(c: AcSetStateCommand): void;
68
78
  }
@@ -1,5 +1,6 @@
1
1
  import { iBaseDevice } from './iBaseDevice';
2
2
  import { iExcessEnergyConsumerSettings } from '../settings';
3
+ import { ExcessEnergyConsumerSetStateCommand } from '../../command';
3
4
  /**
4
5
  * This interface represents a device that can consume excess energy.
5
6
  *
@@ -25,13 +26,13 @@ export interface iExcessEnergyConsumer extends iBaseDevice {
25
26
  */
26
27
  isAvailableForExcessEnergy(): boolean;
27
28
  /**
28
- * Turn on this device to consume excess energy
29
+ * Start or stop this device following an energy-manager decision.
30
+ *
31
+ * One entry point rather than separate turn-on/turn-off methods, so the desired state can
32
+ * only come from the command and cannot contradict the method that was called.
33
+ * @param c - The decision this results from, carrying the measurement it was based on
29
34
  */
30
- turnOnForExcessEnergy(): void;
31
- /**
32
- * Turn off this device as we don't have enough excess energy to power it
33
- */
34
- turnOffDueToMissingEnergy(): void;
35
+ setExcessEnergyState(c: ExcessEnergyConsumerSetStateCommand): void;
35
36
  /**
36
37
  * Check if this device was activated by excess energy
37
38
  * @returns Whether this device was activated by excess energy
@@ -2,6 +2,8 @@ import { iBaseGroup } from './iBaseGroup';
2
2
  import { iAcDevice, iHeater, iHumidityCollector, iTemperatureCollector } from '../baseDevices';
3
3
  import { iTemperatureSettings } from '../settings';
4
4
  import { iHeatGroupSettings } from './iHeatGroupSettings';
5
+ import { CommandSource } from '../../enums';
6
+ import { iBaseCommand } from '../../command';
5
7
  /**
6
8
  *
7
9
  */
@@ -44,11 +46,10 @@ export interface iHeatGroup extends iBaseGroup {
44
46
  initialize(): void;
45
47
  /**
46
48
  * Sets all ACs to new desired Value
47
- * TODO: Migrate to new Command System
48
49
  * @param newDesiredState - The new desired (on/off) state
49
- * @param force - Whether this was a manual trigger, thus blocking automatic changes for 1 hour
50
+ * @param source - The event this results from, so the device command can be traced back to it
50
51
  */
51
- setAc(newDesiredState: boolean, force: boolean): void;
52
+ setAc(newDesiredState: boolean, source: CommandSource | iBaseCommand): void;
52
53
  /**
53
54
  *
54
55
  */
@@ -2,6 +2,7 @@ import { AcSettings, RoomBaseDevice } from '../../devices';
2
2
  import { iAcDevice, iExcessEnergyConsumer, iTemporaryDisableAutomatic } from '../../interfaces';
3
3
  import { AcDeviceType, AcMode, DeviceType } from '../../enums';
4
4
  import { BlockAutomaticHandler } from '../blockAutomaticHandler';
5
+ import { AcPerformAutomaticCheckCommand, AcSetStateCommand, AcWriteStateToDeviceCommand, ExcessEnergyConsumerSetStateCommand, RestoreTargetAutomaticValueCommand } from '../../command';
5
6
  import { ExcessEnergyConsumerSettings } from '../../settingsObjects';
6
7
  export declare abstract class AcDevice extends RoomBaseDevice implements iExcessEnergyConsumer, iAcDevice, iTemporaryDisableAutomatic {
7
8
  ip: string;
@@ -49,13 +50,22 @@ export declare abstract class AcDevice extends RoomBaseDevice implements iExcess
49
50
  abstract get on(): boolean;
50
51
  initializeRoomCbs(): void;
51
52
  /** @inheritDoc */
52
- restoreTargetAutomaticValue(): void;
53
+ restoreTargetAutomaticValue(c: RestoreTargetAutomaticValueCommand): void;
53
54
  /** @inheritDoc */
54
55
  isAvailableForExcessEnergy(): boolean;
55
56
  /** @inheritDoc */
56
57
  calculateDesiredMode(): AcMode;
57
58
  abstract setDesiredMode(mode: AcMode, writeToDevice: boolean, temp?: number): void;
58
- abstract turnOn(): void;
59
+ /**
60
+ * Performs a power write, applying any automatic block the command carries.
61
+ *
62
+ * Single place where a block from a write command is honoured, so callers never have to
63
+ * follow up with a separate disableAutomatic call. A block is not a device setting, so it
64
+ * belongs on a pure power write just as much as on a state change.
65
+ * @param c - The command to execute
66
+ */
67
+ writeStateToDevice(c: AcWriteStateToDeviceCommand): void;
68
+ abstract turnOn(c: AcWriteStateToDeviceCommand): void;
59
69
  /** @inheritDoc */
60
70
  onTemperaturChange(newTemperatur: number): void;
61
71
  /**
@@ -63,22 +73,44 @@ export declare abstract class AcDevice extends RoomBaseDevice implements iExcess
63
73
  */
64
74
  persist(): void;
65
75
  /** @inheritDoc */
66
- turnOnForExcessEnergy(): void;
67
- abstract turnOff(): void;
68
- /** @inheritDoc */
69
- turnOffDueToMissingEnergy(): void;
76
+ setExcessEnergyState(c: ExcessEnergyConsumerSetStateCommand): void;
77
+ abstract turnOff(c: AcWriteStateToDeviceCommand): void;
70
78
  /**
71
- * Sets the state of the AC
72
- * TODO: Migrate to new command system
73
- * @param mode - The desired mode
74
- * @param desiredTemp - The desired temperature (if unset it will be calculated)
75
- * @param forceTime - The time in ms to force the AC to stay in this state (default 1h)
79
+ * Sets the state of the AC.
80
+ *
81
+ * Single entry point for every state change, so each one lands in the command log and
82
+ * the reason a unit switched can be reconstructed afterwards. Callers that represent an
83
+ * automatic decision pass no disableAutomaticCommand, so they do not block themselves.
84
+ * @param c - The command to execute
76
85
  */
77
- setState(mode: AcMode, desiredTemp?: number, forceTime?: number): void;
86
+ setAcState(c: AcSetStateCommand): void;
78
87
  /** @inheritDoc */
79
88
  wasActivatedByExcessEnergy(): boolean;
80
- protected automaticCheck(): void;
89
+ /**
90
+ * Re-evaluates what the state should be and applies it.
91
+ * @param c - The command asking for the re-evaluation; the resulting device command chains
92
+ * from it, so the log shows what triggered the change
93
+ */
94
+ protected automaticCheck(c: AcPerformAutomaticCheckCommand): void;
81
95
  private onRoomAnyMovement;
96
+ /**
97
+ * Keeps the unit off for as long as the room counts as occupied - renewed by every movement.
98
+ *
99
+ * Without a block, staying off depended on the five-minute interval check noticing that somebody
100
+ * is present, and coming back on depended on the last-leave callback arriving. The block replaces
101
+ * both with one timer: every movement pushes it out, and its expiry reverts to automatic by
102
+ * itself, so the room cools again shortly after it empties rather than at the next check.
103
+ *
104
+ * The duration is the room's own movementResetTimer - the same span that decides when the room
105
+ * counts as empty. Anything shorter would let the unit start up with somebody still sitting there;
106
+ * a separate constant would be a second answer to a question the room already answers.
107
+ *
108
+ * The collision strategy is deliberately left at its default (overrideIfGreater): a long press on
109
+ * the wall button sets a much longer block, and walking past the unit must not cut that short.
110
+ * @param c - The command the block chains from, so the log shows what triggered it
111
+ * @returns The block, or undefined when the device has no room to take the duration from
112
+ */
113
+ private buildMovementBlock;
82
114
  private onRoomLastLeave;
83
115
  /** @inheritDoc */
84
116
  toJSON(): Partial<AcDevice>;
@@ -67,7 +67,7 @@ class AcDevice extends devices_1.RoomBaseDevice {
67
67
  this.deviceCapabilities.push(enums_1.DeviceCapability.ac);
68
68
  this.deviceCapabilities.push(enums_1.DeviceCapability.blockAutomatic);
69
69
  this.deviceCapabilities.push(enums_1.DeviceCapability.excessEnergyConsumer);
70
- utils_1.Utils.guardedInterval(this.automaticCheck, 5 * 60 * 1000, this, false);
70
+ utils_1.Utils.guardedInterval(() => this.automaticCheck(new command_1.AcPerformAutomaticCheckCommand(enums_1.CommandSource.Automatic, 'Time interval check')), 5 * 60 * 1000, this, false);
71
71
  utils_1.Utils.guardedInterval(this.persist, 15 * 60 * 1000, this, true);
72
72
  this.blockAutomationHandler = new blockAutomaticHandler_1.BlockAutomaticHandler(this.restoreTargetAutomaticValue.bind(this), this.log.bind(this));
73
73
  }
@@ -100,16 +100,14 @@ class AcDevice extends devices_1.RoomBaseDevice {
100
100
  }
101
101
  utils_1.Utils.guardedFunction(() => {
102
102
  var _a, _b;
103
- // TODO: Maybe change to any Movement
104
103
  (_a = this.room.PraesenzGroup) === null || _a === void 0 ? void 0 : _a.addAnyMovementCallback(this.onRoomAnyMovement.bind(this));
105
104
  (_b = this.room.PraesenzGroup) === null || _b === void 0 ? void 0 : _b.addLastLeftCallback(this.onRoomLastLeave.bind(this));
106
105
  this._movementCallbackAdded = true;
107
106
  }, this);
108
107
  }
109
108
  /** @inheritDoc */
110
- restoreTargetAutomaticValue() {
111
- this.log(enums_1.LogLevel.Debug, 'Restore Target Automatic value');
112
- this.automaticCheck();
109
+ restoreTargetAutomaticValue(c) {
110
+ this.automaticCheck(new command_1.AcPerformAutomaticCheckCommand(c, 'Restore automatic value'));
113
111
  }
114
112
  /** @inheritDoc */
115
113
  isAvailableForExcessEnergy() {
@@ -222,6 +220,24 @@ class AcDevice extends devices_1.RoomBaseDevice {
222
220
  }
223
221
  return desiredMode;
224
222
  }
223
+ /**
224
+ * Performs a power write, applying any automatic block the command carries.
225
+ *
226
+ * Single place where a block from a write command is honoured, so callers never have to
227
+ * follow up with a separate disableAutomatic call. A block is not a device setting, so it
228
+ * belongs on a pure power write just as much as on a state change.
229
+ * @param c - The command to execute
230
+ */
231
+ writeStateToDevice(c) {
232
+ if (c.disableAutomaticCommand) {
233
+ this.blockAutomationHandler.disableAutomatic(c.disableAutomaticCommand);
234
+ }
235
+ if (c.on) {
236
+ this.turnOn(c);
237
+ return;
238
+ }
239
+ this.turnOff(c);
240
+ }
225
241
  /** @inheritDoc */
226
242
  onTemperaturChange(newTemperatur) {
227
243
  this.roomTemperatur = newTemperatur;
@@ -237,47 +253,67 @@ class AcDevice extends devices_1.RoomBaseDevice {
237
253
  (_a = dbo_1.Persistence.dbo) === null || _a === void 0 ? void 0 : _a.persistAC(this);
238
254
  }
239
255
  /** @inheritDoc */
240
- turnOnForExcessEnergy() {
256
+ setExcessEnergyState(c) {
241
257
  var _a, _b;
258
+ if (!c.on) {
259
+ this.setAcState(new command_1.AcSetStateCommand(c, enums_1.AcMode.Off, undefined, 'Missing excess energy'));
260
+ return;
261
+ }
242
262
  if (this.blockAutomationHandler.automaticBlockActive) {
243
263
  return;
244
264
  }
245
- this._activatedByExcessEnergy = true;
246
265
  const desiredMode = this.calculateDesiredMode();
266
+ if (desiredMode === enums_1.AcMode.Off) {
267
+ // isAvailableForExcessEnergy does not cover manualDisabled or an ac-blocking energy
268
+ // manager, so the device can still say it wants to stay off. Leave it alone rather than
269
+ // forcing it on, and do not claim it was activated by excess energy.
270
+ this.logCommand(c, 'Excess energy offered, but the device wants to stay off', enums_1.LogDebugType.SkipUnchangedActuatorCommand);
271
+ return;
272
+ }
247
273
  if (desiredMode === enums_1.AcMode.Cooling &&
248
274
  this.settings.noCoolingOnMovement &&
249
275
  ((_b = (_a = this.room) === null || _a === void 0 ? void 0 : _a.PraesenzGroup) === null || _b === void 0 ? void 0 : _b.anyPresent(true))) {
250
276
  return;
251
277
  }
252
- this.setDesiredMode(this.calculateDesiredMode(), false);
253
- this.turnOn();
254
- }
255
- /** @inheritDoc */
256
- turnOffDueToMissingEnergy() {
257
- this.turnOff();
278
+ this._activatedByExcessEnergy = true;
279
+ this.setAcState(new command_1.AcSetStateCommand(c, desiredMode, undefined, 'Excess energy available'));
258
280
  }
259
281
  /**
260
- * Sets the state of the AC
261
- * TODO: Migrate to new command system
262
- * @param mode - The desired mode
263
- * @param desiredTemp - The desired temperature (if unset it will be calculated)
264
- * @param forceTime - The time in ms to force the AC to stay in this state (default 1h)
282
+ * Sets the state of the AC.
283
+ *
284
+ * Single entry point for every state change, so each one lands in the command log and
285
+ * the reason a unit switched can be reconstructed afterwards. Callers that represent an
286
+ * automatic decision pass no disableAutomaticCommand, so they do not block themselves.
287
+ * @param c - The command to execute
265
288
  */
266
- setState(mode, desiredTemp, forceTime = 60 * 60 * 1000) {
267
- this.blockAutomationHandler.disableAutomatic(new command_1.BlockAutomaticCommand(enums_1.CommandSource.Unknown, forceTime));
289
+ setAcState(c) {
290
+ var _a;
291
+ this.logCommand(c);
292
+ if (c.disableAutomaticCommand) {
293
+ this.blockAutomationHandler.disableAutomatic(c.disableAutomaticCommand);
294
+ }
295
+ // An unset mode means "just switch it on" - which mode that is depends on season and
296
+ // settings, so the device resolves it rather than the caller.
297
+ const mode = (_a = c.mode) !== null && _a !== void 0 ? _a : (this.heatingAllowed ? enums_1.AcMode.Heating : enums_1.AcMode.Cooling);
268
298
  this._mode = mode;
269
- if (mode == enums_1.AcMode.Off) {
270
- this.turnOff();
271
- return;
299
+ // The write command chains back to this one, so the device log shows both the
300
+ // intent and the actual power write, mirroring the actuator path.
301
+ const writeCommand = new command_1.AcWriteStateToDeviceCommand(c, c.on);
302
+ if (c.on) {
303
+ this.setDesiredMode(mode, false, c.desiredTemperature);
272
304
  }
273
- this.setDesiredMode(mode, false, desiredTemp);
274
- this.turnOn();
305
+ this.writeStateToDevice(writeCommand);
275
306
  }
276
307
  /** @inheritDoc */
277
308
  wasActivatedByExcessEnergy() {
278
309
  return this._activatedByExcessEnergy;
279
310
  }
280
- automaticCheck() {
311
+ /**
312
+ * Re-evaluates what the state should be and applies it.
313
+ * @param c - The command asking for the re-evaluation; the resulting device command chains
314
+ * from it, so the log shows what triggered the change
315
+ */
316
+ automaticCheck(c) {
281
317
  var _a, _b;
282
318
  if (this.blockAutomationHandler.automaticBlockActive) {
283
319
  // We aren't allowed to turn on or off anyway --> exit
@@ -288,29 +324,57 @@ class AcDevice extends devices_1.RoomBaseDevice {
288
324
  // Device already in desired state --> do nothing
289
325
  return;
290
326
  }
327
+ // Kept ahead of the branch as before: turning off still reports the mode we would
328
+ // otherwise have wanted, which setDesiredInfo sends alongside the power state.
291
329
  this.setDesiredMode(desiredMode, false);
292
330
  if (desiredMode == enums_1.AcMode.Off ||
293
331
  (desiredMode === enums_1.AcMode.Cooling &&
294
332
  this.settings.noCoolingOnMovement &&
295
333
  ((_b = (_a = this.room) === null || _a === void 0 ? void 0 : _a.PraesenzGroup) === null || _b === void 0 ? void 0 : _b.anyPresent(true)))) {
296
- this.turnOff();
334
+ this.setAcState(new command_1.AcSetStateCommand(c, enums_1.AcMode.Off, undefined, 'No cooling wanted'));
297
335
  return;
298
336
  }
299
- this.turnOn();
337
+ this.setAcState(new command_1.AcSetStateCommand(c, desiredMode, undefined, 'Desired mode reached'));
300
338
  }
301
- onRoomAnyMovement(_action) {
339
+ onRoomAnyMovement(action) {
302
340
  if (!this.settings.noCoolingOnMovement || !this.on || this.mode === enums_1.AcMode.Heating) {
303
341
  return;
304
342
  }
305
- this.log(enums_1.LogLevel.Info, 'Something moved in the room. Turning off AC');
306
- this.turnOff();
343
+ this.setAcState(new command_1.AcSetStateCommand(action, enums_1.AcMode.Off, undefined, 'Something moved in the room and noCoolingOnMovement is set.', this.buildMovementBlock(action)));
344
+ }
345
+ /**
346
+ * Keeps the unit off for as long as the room counts as occupied - renewed by every movement.
347
+ *
348
+ * Without a block, staying off depended on the five-minute interval check noticing that somebody
349
+ * is present, and coming back on depended on the last-leave callback arriving. The block replaces
350
+ * both with one timer: every movement pushes it out, and its expiry reverts to automatic by
351
+ * itself, so the room cools again shortly after it empties rather than at the next check.
352
+ *
353
+ * The duration is the room's own movementResetTimer - the same span that decides when the room
354
+ * counts as empty. Anything shorter would let the unit start up with somebody still sitting there;
355
+ * a separate constant would be a second answer to a question the room already answers.
356
+ *
357
+ * The collision strategy is deliberately left at its default (overrideIfGreater): a long press on
358
+ * the wall button sets a much longer block, and walking past the unit must not cut that short.
359
+ * @param c - The command the block chains from, so the log shows what triggered it
360
+ * @returns The block, or undefined when the device has no room to take the duration from
361
+ */
362
+ buildMovementBlock(c) {
363
+ var _a, _b;
364
+ const occupiedForSeconds = (_b = (_a = this.room) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.movementResetTimer;
365
+ // No room means no answer to "how long does this count as occupied". Switching off without a
366
+ // block is what happened before this existed, and it is the honest fallback - a made-up
367
+ // duration would block the automatic for a span nothing chose.
368
+ if (occupiedForSeconds === undefined || occupiedForSeconds <= 0) {
369
+ return undefined;
370
+ }
371
+ return new command_1.BlockAutomaticCommand(c, occupiedForSeconds * 1000, 'noCoolingOnMovement', undefined, true);
307
372
  }
308
373
  onRoomLastLeave(action) {
309
374
  if (!this.settings.noCoolingOnMovement) {
310
375
  return;
311
376
  }
312
- this.log(enums_1.LogLevel.Info, `Last person left the room (${action.reasonTrace}). Checking if we should turn on AC`);
313
- this.restoreTargetAutomaticValue();
377
+ this.restoreTargetAutomaticValue(new command_1.RestoreTargetAutomaticValueCommand(action, 'Last person left the room, whilst noCoolingOnMovement is set'));
314
378
  }
315
379
  /** @inheritDoc */
316
380
  toJSON() {
@@ -1,5 +1,6 @@
1
1
  import { DaikinAC, DaikinManager } from 'daikin-controller';
2
2
  import { AcDevice } from './ac-device';
3
+ import { AcWriteStateToDeviceCommand } from '../../command';
3
4
  export declare class DaikinService {
4
5
  private static _ownDevices;
5
6
  private static _daikinManager;
@@ -11,7 +12,7 @@ export declare class DaikinService {
11
12
  }): void;
12
13
  static getDevice(name: string): DaikinAC | undefined;
13
14
  static initialize(): Promise<void>;
14
- static setAll(on: boolean, force?: boolean): void;
15
+ static setAll(c: AcWriteStateToDeviceCommand, force?: boolean): void;
15
16
  static reconnect(name: string, ip: string, mac?: string): Promise<DaikinAC | undefined>;
16
17
  private static reconstructDaikinAc;
17
18
  private static initializeDevice;
@@ -38,14 +38,14 @@ class DaikinService {
38
38
  Telegram_1.TelegramService.addMessageCallback(new Telegram_1.TelegramMessageCallback('AcOn', /\/ac_on/, async (m) => {
39
39
  if (m.from === undefined)
40
40
  return false;
41
- DaikinService.setAll(true);
41
+ DaikinService.setAll(new command_1.AcWriteStateToDeviceCommand(enums_1.CommandSource.Manual, true, `Telegram /ac_on by ${m.from.id}`));
42
42
  Telegram_1.TelegramService.sendMessage([m.chat.id], 'Command executed');
43
43
  return true;
44
44
  }, "Turns all Ac's on without changing any settings"));
45
45
  Telegram_1.TelegramService.addMessageCallback(new Telegram_1.TelegramMessageCallback('AcOff', /\/ac_off/, async (m) => {
46
46
  if (m.from === undefined)
47
47
  return false;
48
- DaikinService.setAll(false, true);
48
+ DaikinService.setAll(new command_1.AcWriteStateToDeviceCommand(enums_1.CommandSource.Manual, false, `Telegram /ac_off by ${m.from.id}`), true);
49
49
  Telegram_1.TelegramService.sendMessage([m.chat.id], 'Command executed');
50
50
  return true;
51
51
  }, "Turns all Ac's off without changing any settings"));
@@ -68,22 +68,17 @@ class DaikinService {
68
68
  });
69
69
  });
70
70
  }
71
- // TODO: Migrate to new command system
72
- static setAll(on, force = false) {
71
+ static setAll(c, force = false) {
73
72
  if (!this.isInitialized) {
74
73
  return;
75
74
  }
76
75
  for (const deviceName in this._ownDevices) {
77
76
  const dev = this._ownDevices[deviceName];
78
- if (on) {
79
- dev.turnOn();
80
- }
81
- else {
82
- dev.turnOff();
83
- }
84
- if (force) {
85
- dev.blockAutomationHandler.disableAutomatic(new command_1.BlockAutomaticCommand(enums_1.CommandSource.Unknown, 180 * 60 * 1000));
86
- }
77
+ // Contract of this method is to switch power without touching any settings, so it
78
+ // addresses the write layer rather than setAcState, which would resolve and apply a mode.
79
+ // The block is not a setting, so it travels in the command like everywhere else.
80
+ c.disableAutomaticCommand = force ? new command_1.BlockAutomaticCommand(c, 180 * 60 * 1000) : undefined;
81
+ dev.writeStateToDevice(c);
87
82
  }
88
83
  }
89
84
  static async reconnect(name, ip, mac) {
@@ -1,4 +1,5 @@
1
1
  import { AcDevice } from './ac-device';
2
+ import { AcPerformAutomaticCheckCommand, AcWriteStateToDeviceCommand } from '../../command';
2
3
  import { DaikinAC } from 'daikin-controller';
3
4
  import { AcMode, DeviceType } from '../../enums';
4
5
  export declare class OwnDaikinDevice extends AcDevice {
@@ -29,10 +30,10 @@ export declare class OwnDaikinDevice extends AcDevice {
29
30
  /** @inheritDoc */
30
31
  setDesiredMode(mode: AcMode, writeToDevice?: boolean, desiredTemp?: number): void;
31
32
  /** @inheritDoc */
32
- turnOn(): void;
33
+ turnOn(c: AcWriteStateToDeviceCommand): void;
33
34
  /** @inheritDoc */
34
- turnOff(): void;
35
- protected automaticCheck(): void;
35
+ turnOff(c: AcWriteStateToDeviceCommand): void;
36
+ protected automaticCheck(c: AcPerformAutomaticCheckCommand): void;
36
37
  private setDesiredInfo;
37
38
  private updateInfo;
38
39
  /**
@@ -77,23 +77,23 @@ class OwnDaikinDevice extends ac_device_1.AcDevice {
77
77
  }
78
78
  }
79
79
  /** @inheritDoc */
80
- turnOn() {
81
- this.log(enums_1.LogLevel.Info, 'Turning on');
80
+ turnOn(c) {
81
+ this.logCommand(c);
82
82
  this.desiredState = daikin_controller_1.Power.ON;
83
83
  this.setDesiredInfo();
84
84
  }
85
85
  /** @inheritDoc */
86
- turnOff() {
87
- this.log(enums_1.LogLevel.Info, 'Turning off');
86
+ turnOff(c) {
87
+ this.logCommand(c);
88
88
  this._activatedByExcessEnergy = false;
89
89
  this.desiredState = daikin_controller_1.Power.OFF;
90
90
  this._mode = enums_1.AcMode.Off;
91
91
  this.setDesiredInfo();
92
92
  }
93
- automaticCheck() {
93
+ automaticCheck(c) {
94
94
  // First Load Device Info, then perform check
95
95
  this.updateInfo().then((_on) => {
96
- super.automaticCheck();
96
+ super.automaticCheck(c);
97
97
  });
98
98
  }
99
99
  setDesiredInfo(retry = false, forceTemp) {