nodejs-poolcontroller 7.7.0 → 8.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 (82) hide show
  1. package/.eslintrc.json +26 -35
  2. package/Changelog +22 -0
  3. package/README.md +7 -3
  4. package/anslq25/MessagesMock.ts +218 -0
  5. package/anslq25/boards/MockBoardFactory.ts +50 -0
  6. package/anslq25/boards/MockEasyTouchBoard.ts +696 -0
  7. package/anslq25/boards/MockSystemBoard.ts +217 -0
  8. package/anslq25/chemistry/MockChlorinator.ts +75 -0
  9. package/anslq25/pumps/MockPump.ts +84 -0
  10. package/app.ts +10 -14
  11. package/config/Config.ts +13 -9
  12. package/config/VersionCheck.ts +6 -2
  13. package/controller/Constants.ts +58 -25
  14. package/controller/Equipment.ts +225 -41
  15. package/controller/Errors.ts +2 -1
  16. package/controller/Lockouts.ts +34 -2
  17. package/controller/State.ts +491 -48
  18. package/controller/boards/AquaLinkBoard.ts +6 -3
  19. package/controller/boards/BoardFactory.ts +5 -1
  20. package/controller/boards/EasyTouchBoard.ts +1971 -1751
  21. package/controller/boards/IntelliCenterBoard.ts +1311 -1688
  22. package/controller/boards/IntelliComBoard.ts +7 -1
  23. package/controller/boards/IntelliTouchBoard.ts +153 -42
  24. package/controller/boards/NixieBoard.ts +209 -66
  25. package/controller/boards/SunTouchBoard.ts +393 -0
  26. package/controller/boards/SystemBoard.ts +1862 -1543
  27. package/controller/comms/Comms.ts +539 -138
  28. package/controller/comms/ScreenLogic.ts +1663 -0
  29. package/controller/comms/messages/Messages.ts +242 -60
  30. package/controller/comms/messages/config/ChlorinatorMessage.ts +4 -3
  31. package/controller/comms/messages/config/CircuitGroupMessage.ts +5 -2
  32. package/controller/comms/messages/config/CircuitMessage.ts +81 -13
  33. package/controller/comms/messages/config/ConfigMessage.ts +3 -1
  34. package/controller/comms/messages/config/CoverMessage.ts +2 -1
  35. package/controller/comms/messages/config/CustomNameMessage.ts +2 -1
  36. package/controller/comms/messages/config/EquipmentMessage.ts +5 -1
  37. package/controller/comms/messages/config/ExternalMessage.ts +33 -3
  38. package/controller/comms/messages/config/FeatureMessage.ts +2 -1
  39. package/controller/comms/messages/config/GeneralMessage.ts +2 -1
  40. package/controller/comms/messages/config/HeaterMessage.ts +3 -1
  41. package/controller/comms/messages/config/IntellichemMessage.ts +2 -1
  42. package/controller/comms/messages/config/OptionsMessage.ts +12 -6
  43. package/controller/comms/messages/config/PumpMessage.ts +9 -12
  44. package/controller/comms/messages/config/RemoteMessage.ts +80 -13
  45. package/controller/comms/messages/config/ScheduleMessage.ts +43 -3
  46. package/controller/comms/messages/config/SecurityMessage.ts +2 -1
  47. package/controller/comms/messages/config/ValveMessage.ts +43 -26
  48. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +8 -7
  49. package/controller/comms/messages/status/EquipmentStateMessage.ts +93 -20
  50. package/controller/comms/messages/status/HeaterStateMessage.ts +24 -5
  51. package/controller/comms/messages/status/IntelliChemStateMessage.ts +7 -4
  52. package/controller/comms/messages/status/IntelliValveStateMessage.ts +2 -1
  53. package/controller/comms/messages/status/PumpStateMessage.ts +72 -4
  54. package/controller/comms/messages/status/VersionMessage.ts +2 -1
  55. package/controller/nixie/Nixie.ts +15 -4
  56. package/controller/nixie/NixieEquipment.ts +1 -0
  57. package/controller/nixie/chemistry/ChemController.ts +300 -129
  58. package/controller/nixie/chemistry/ChemDoser.ts +806 -0
  59. package/controller/nixie/chemistry/Chlorinator.ts +133 -129
  60. package/controller/nixie/circuits/Circuit.ts +171 -30
  61. package/controller/nixie/heaters/Heater.ts +337 -173
  62. package/controller/nixie/pumps/Pump.ts +264 -236
  63. package/controller/nixie/schedules/Schedule.ts +9 -3
  64. package/defaultConfig.json +46 -5
  65. package/logger/Logger.ts +38 -9
  66. package/package.json +13 -9
  67. package/web/Server.ts +235 -122
  68. package/web/bindings/aqualinkD.json +114 -59
  69. package/web/bindings/homeassistant.json +437 -0
  70. package/web/bindings/influxDB.json +15 -0
  71. package/web/bindings/mqtt.json +28 -9
  72. package/web/bindings/mqttAlt.json +15 -0
  73. package/web/interfaces/baseInterface.ts +58 -7
  74. package/web/interfaces/httpInterface.ts +5 -2
  75. package/web/interfaces/influxInterface.ts +9 -2
  76. package/web/interfaces/mqttInterface.ts +234 -74
  77. package/web/interfaces/ruleInterface.ts +87 -0
  78. package/web/services/config/Config.ts +140 -33
  79. package/web/services/config/ConfigSocket.ts +2 -1
  80. package/web/services/state/State.ts +144 -3
  81. package/web/services/state/StateSocket.ts +65 -14
  82. package/web/services/utilities/Utilities.ts +189 -1
@@ -1,5 +1,6 @@
1
1
  /* nodejs-poolController. An application to control pool equipment.
2
- Copyright (C) 2016, 2017, 2018, 2019, 2020. Russell Goldin, tagyoureit. russ.goldin@gmail.com
2
+ Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022.
3
+ Russell Goldin, tagyoureit. russ.goldin@gmail.com
3
4
 
4
5
  This program is free software: you can redistribute it and/or modify
5
6
  it under the terms of the GNU Affero General Public License as
@@ -177,6 +178,8 @@ export class Heliotrope {
177
178
  public get calculatedTimes(): any { return { sunrise: this.sunrise, sunset: this.sunset, isValid: this.isValid }; }
178
179
  }
179
180
  export class Timestamp {
181
+ private static dateTextISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
182
+ private static dateTextAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
180
183
  private _dt: Date;
181
184
  public emitter: EventEmitter;
182
185
  constructor(dt?: Date | string) {
@@ -187,8 +190,8 @@ export class Timestamp {
187
190
  private _isUpdating: boolean = false;
188
191
  public static get now(): Timestamp { return new Timestamp(); }
189
192
  public toDate() { return this._dt; }
190
- public set isUpdating(val:boolean) {this._isUpdating = val;}
191
- public get isUpdating(): boolean { return this._isUpdating;}
193
+ public set isUpdating(val: boolean) { this._isUpdating = val; }
194
+ public get isUpdating(): boolean { return this._isUpdating; }
192
195
  public get hours(): number { return this._dt.getHours(); }
193
196
  public set hours(val: number) {
194
197
  if (this.hours !== val) {
@@ -261,8 +264,8 @@ export class Timestamp {
261
264
  dt.getFullYear() !== this._dt.getFullYear())
262
265
  this.emitter.emit('change');
263
266
  }
264
- public calcTZOffset(): {tzOffset:number, adjustDST:boolean}{
265
- let obj = {tzOffset: 0, adjustDST: false};
267
+ public calcTZOffset(): { tzOffset: number, adjustDST: boolean } {
268
+ let obj = { tzOffset: 0, adjustDST: false };
266
269
  let dateJan = new Date(this._dt.getFullYear(), 0, 1, 2);
267
270
  let dateJul = new Date(this._dt.getFullYear(), 6, 1, 2);
268
271
  obj.tzOffset = dateJan.getTimezoneOffset() / 60 * -1;
@@ -293,6 +296,15 @@ export class Timestamp {
293
296
  }
294
297
  public clone() { return new Timestamp(new Date(this._dt)); }
295
298
  public static locale() { return Intl.DateTimeFormat().resolvedOptions().locale; }
299
+ public static parseISO(val: string): RegExpExecArray { return typeof val !== 'undefined' && val ? Timestamp.dateTextISO.exec(val) : null; }
300
+ public static parseAjax(val: string): RegExpExecArray { return typeof val !== 'undefined' && val ? Timestamp.dateTextAjax.exec(val) : null; }
301
+ public static dayOfWeek(time: Timestamp): number {
302
+ // for IntelliTouch set date/time
303
+ if (time.toDate().getUTCDay() === 0)
304
+ return 0;
305
+ else
306
+ return Math.pow(2, time.toDate().getUTCDay() - 1);
307
+ }
296
308
  }
297
309
  export enum ControllerType {
298
310
  IntelliCenter = 'intellicenter',
@@ -300,27 +312,12 @@ export enum ControllerType {
300
312
  IntelliCom = 'intellicom',
301
313
  EasyTouch = 'easytouch',
302
314
  Unknown = 'unknown',
303
- Virtual = 'virtual',
315
+ // Virtual = 'virtual',
304
316
  Nixie = 'nixie',
305
- AquaLink = 'aqualink'
317
+ AquaLink = 'aqualink',
318
+ SunTouch = 'suntouch',
319
+ None = 'none'
306
320
  }
307
- // export enum VirtualDeviceType {
308
- // Pump = 'pump',
309
- // Chlorinator = 'chlorinator'
310
- // }
311
- //export class Enums {
312
- // public static Addresses = {
313
- // 2: { val: 2, name: 'chlorinator', desc: 'Chlorinator' },
314
- // 15: { val: 15, name: 'outdoor', desc: 'Main outdoor panel' },
315
- // 16: { val: 16, name: 'broadcast', desc: 'Broadcast' },
316
- // 33: { val: 33, name: 'intellitouch', desc: 'Intellitouch Plugin' },
317
- // 34: { val: 34, name: 'mobi', desc: 'Wireless controller' },
318
- // 36: { val: 36, name: 'intellicenter', desc: 'Intellicenter Plugin' },
319
- // 37: { val: 37, name: 'indoor2', desc: 'Indoor panel #2' },
320
- // 144: { val: 144, name: 'intellichem', desc: 'Intellichem' },
321
- // transform: function (byte) { return extend(true, {}, this[byte] || this[0]); }
322
- // }
323
- //}
324
321
 
325
322
  export class Utils {
326
323
  public makeBool(val) {
@@ -345,6 +342,32 @@ export class Utils {
345
342
  }
346
343
  return false;
347
344
  }
345
+ public static jsonReviver = (key, value) => {
346
+ if (typeof value === 'string') {
347
+ let d = Timestamp.parseISO(value);
348
+ // By parsing the date and then creating a new date from that we will get
349
+ // the date in the proper timezone.
350
+ if (d) return new Date(Date.parse(value));
351
+ d = Timestamp.parseAjax(value);
352
+ if (d) {
353
+ // Not sure we will be seeing ajax dates but this is
354
+ // something that we may see from external sources.
355
+ let a = d[1].split(/[-+,.]/);
356
+ return new Date(a[0] ? +a[0] : 0 - +a[1]);
357
+ }
358
+ }
359
+ return value;
360
+ }
361
+ public static jsonReplacer = (key, value) => {
362
+ // Add in code to change Timestamp into a string.
363
+ if (typeof value !== 'undefined' && value) {
364
+ if (typeof value.format === 'function') return value.format();
365
+ else if (typeof value.getTime === 'function') return Timestamp.toISOLocal(value);
366
+ }
367
+ return value;
368
+ }
369
+ public static parseJSON(json: string) { return JSON.parse(json, Utils.jsonReviver); }
370
+ public static stringifyJSON(obj: any) { return JSON.stringify(obj, Utils.jsonReplacer); }
348
371
  public uuid(a?, b?) { for (b = a = ''; a++ < 36; b += a * 51 & 52 ? (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-'); return b }
349
372
  public convert = {
350
373
  temperature: {
@@ -570,7 +593,7 @@ export class Utils {
570
593
  return seconds;
571
594
  }
572
595
  public isNullOrEmpty(val: any) { return (typeof val === 'string') ? val === null || val === '' : typeof val === 'undefined' || val === null; }
573
- public sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
596
+ // public sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
574
597
  // Use this method to get around the circular references for the toJSON function.
575
598
  public serialize(obj, fn?: (key, value) => any): string {
576
599
  let op = Object.getOwnPropertyNames(obj);
@@ -671,6 +694,16 @@ export class Utils {
671
694
  let slope = (points_y[0] - points_y[points_y.length - 1]) / (points_x[0] - points_x[points_x.length - 1]);
672
695
  return slope;
673
696
  }
697
+ private random(bounds: number, onlyPositive: boolean = false) {
698
+ let rand = Math.random() * bounds;
699
+ if (!onlyPositive) {
700
+ if (Math.random() <= .5) rand = rand * -1;
701
+ }
702
+ return rand;
703
+ }
704
+ public dec2bin(dec) {
705
+ return (dec >>> 0).toString(2).padStart(8, '0');
706
+ }
674
707
  }
675
708
 
676
709
  export const utils = new Utils();