nodejs-poolcontroller 8.1.1 → 8.1.2

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.
package/README.md CHANGED
@@ -106,11 +106,11 @@ To do anything with this app, you need a client to connect to it. A client can
106
106
  ## Home Automation Bindings (previously Integrations)
107
107
 
108
108
  Available automations:
109
- * [Vera Home Automation Hub](https://github.com/rstrouse/nodejs-poolController-veraPlugin) - A plugin that integrates with nodejs-poolController. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations-in-2.0#vera)
110
- * [Hubitat](https://github.com/bsileo/hubitat_poolcontroller) by @bsileo (prev help from @johnny2678, @donkarnag, @arrmo). [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations-in-2.0#smartthingshubitat)
109
+ * [Vera Home Automation Hub](https://github.com/rstrouse/nodejs-poolController-veraPlugin) - A plugin that integrates with nodejs-poolController. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#vera)
110
+ * [Hubitat](https://github.com/bsileo/hubitat_poolcontroller) by @bsileo (prev help from @johnny2678, @donkarnag, @arrmo). [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#smartthingshubitat)
111
111
  * [Homebridge/Siri/EVE](https://github.com/gadget-monk/homebridge-poolcontroller) by @gadget-monk, adopted from @leftyflip
112
- * InfluxDB - [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations-in-2.0#influx)
113
- * [MQTT](https://github.com/crsherman/nodejs-poolController-mqtt) original release by @crsherman, re-write by @kkzonie, testing by @baudfather and others. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations-in-2.0#mqtt)
112
+ * InfluxDB - [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#influx)
113
+ * [MQTT](https://github.com/crsherman/nodejs-poolController-mqtt) original release by @crsherman, re-write by @kkzonie, testing by @baudfather and others. [Bindings Directions](https://github.com/tagyoureit/nodejs-poolController/wiki/Bindings-Integrations#mqtt)
114
114
  * [Homeseer](https://github.com/tagyoureit/nodejs-poolController/wiki/Homeseer-Setup-Instructions) - Integration directions by @miamijerry to integrate Homeseer through MQTT
115
115
 
116
116
  Outdated:
@@ -3030,8 +3030,8 @@ class TouchChemControllerCommands extends ChemControllerCommands {
3030
3030
  if (isNaN(alkalinity)) return Promise.reject(new InvalidEquipmentDataError(`Invalid alkalinity`, 'chemController', alkalinity));
3031
3031
  if (isNaN(borates)) return Promise.reject(new InvalidEquipmentDataError(`Invalid borates`, 'chemController', borates));
3032
3032
  let schem = state.chemControllers.getItemById(chem.id, true);
3033
- let pHSetpoint = typeof data.ph !== 'undefined' && typeof data.ph.setpoint !== 'undefined' ? parseFloat(data.ph.setpoint) : chem.ph.setpoint;
3034
- let orpSetpoint = typeof data.orp !== 'undefined' && typeof data.orp.setpoint !== 'undefined' ? parseInt(data.orp.setpoint, 10) : chem.orp.setpoint;
3033
+ let pHSetpoint = (typeof data.ph !== 'undefined' && typeof data.ph.setpoint !== 'undefined') ? parseFloat(data.ph.setpoint) : chem.ph.setpoint;
3034
+ let orpSetpoint = (typeof data.orp !== 'undefined' && typeof data.orp.setpoint !== 'undefined') ? parseInt(data.orp.setpoint, 10) : chem.orp.setpoint;
3035
3035
  let lsiRange = typeof data.lsiRange !== 'undefined' ? data.lsiRange : chem.lsiRange || {};
3036
3036
  if (typeof data.lsiRange !== 'undefined') {
3037
3037
  if (typeof data.lsiRange.enabled !== 'undefined') lsiRange.enabled = utils.makeBool(data.lsiRange.enabled);
@@ -3040,31 +3040,31 @@ class TouchChemControllerCommands extends ChemControllerCommands {
3040
3040
  }
3041
3041
  if (isNaN(pHSetpoint) || pHSetpoint > type.ph.max || pHSetpoint < type.ph.min) return Promise.reject(new InvalidEquipmentDataError(`Invalid pH setpoint`, 'ph.setpoint', pHSetpoint));
3042
3042
  if (isNaN(orpSetpoint) || orpSetpoint > type.orp.max || orpSetpoint < type.orp.min) return Promise.reject(new InvalidEquipmentDataError(`Invalid orp setpoint`, 'orp.setpoint', orpSetpoint));
3043
- let phTolerance = typeof data.ph.tolerance !== 'undefined' ? data.ph.tolerance : chem.ph.tolerance;
3044
- let orpTolerance = typeof data.orp.tolerance !== 'undefined' ? data.orp.tolerance : chem.orp.tolerance;
3045
- if (typeof data.ph.tolerance !== 'undefined') {
3043
+ let phTolerance = (typeof data.ph !== 'undefined' && typeof data.ph.tolerance !== 'undefined') ? data.ph.tolerance : chem.ph.tolerance;
3044
+ let orpTolerance = (typeof data.orp !== 'undefined' && typeof data.orp.tolerance !== 'undefined') ? data.orp.tolerance : chem.orp.tolerance;
3045
+ if (typeof data.ph !== 'undefined' && typeof data.ph.tolerance !== 'undefined') {
3046
3046
  if (typeof data.ph.tolerance.enabled !== 'undefined') phTolerance.enabled = utils.makeBool(data.ph.tolerance.enabled);
3047
3047
  if (typeof data.ph.tolerance.low !== 'undefined') phTolerance.low = parseFloat(data.ph.tolerance.low);
3048
3048
  if (typeof data.ph.tolerance.high !== 'undefined') phTolerance.high = parseFloat(data.ph.tolerance.high);
3049
3049
  if (isNaN(phTolerance.low)) phTolerance.low = type.ph.min;
3050
3050
  if (isNaN(phTolerance.high)) phTolerance.high = type.ph.max;
3051
3051
  }
3052
- if (typeof data.orp.tolerance !== 'undefined') {
3052
+ if (typeof data.orp !== 'undefined' && typeof data.orp.tolerance !== 'undefined') {
3053
3053
  if (typeof data.orp.tolerance.enabled !== 'undefined') orpTolerance.enabled = utils.makeBool(data.orp.tolerance.enabled);
3054
3054
  if (typeof data.orp.tolerance.low !== 'undefined') orpTolerance.low = parseFloat(data.orp.tolerance.low);
3055
3055
  if (typeof data.orp.tolerance.high !== 'undefined') orpTolerance.high = parseFloat(data.orp.tolerance.high);
3056
3056
  if (isNaN(orpTolerance.low)) orpTolerance.low = type.orp.min;
3057
3057
  if (isNaN(orpTolerance.high)) orpTolerance.high = type.orp.max;
3058
3058
  }
3059
- let phEnabled = typeof data.ph.enabled !== 'undefined' ? utils.makeBool(data.ph.enabled) : chem.ph.enabled;
3060
- let orpEnabled = typeof data.orp.enabled !== 'undefined' ? utils.makeBool(data.orp.enabled) : chem.orp.enabled;
3059
+ let phEnabled = (typeof data.ph !== 'undefined' && typeof data.ph.enabled !== 'undefined') ? utils.makeBool(data.ph.enabled) : chem.ph.enabled;
3060
+ let orpEnabled = (typeof data.orp !== 'undefined' && typeof data.orp.enabled !== 'undefined') ? utils.makeBool(data.orp.enabled) : chem.orp.enabled;
3061
3061
  let siCalcType = typeof data.siCalcType !== 'undefined' ? sys.board.valueMaps.siCalcTypes.encode(data.siCalcType, 0) : chem.siCalcType;
3062
3062
 
3063
3063
  let saltLevel = (state.chlorinators.length > 0) ? state.chlorinators.getItemById(1).saltLevel || 1000 : 1000
3064
3064
  chem.ph.tank.capacity = 6;
3065
3065
  chem.orp.tank.capacity = 6;
3066
- let acidTankLevel = typeof data.ph !== 'undefined' && typeof data.ph.tank !== 'undefined' && typeof data.ph.tank.level !== 'undefined' ? parseInt(data.ph.tank.level, 10) : schem.ph.tank.level;
3067
- let orpTankLevel = typeof data.orp !== 'undefined' && typeof data.orp.tank !== 'undefined' && typeof data.orp.tank.level !== 'undefined' ? parseInt(data.orp.tank.level, 10) : schem.orp.tank.level;
3066
+ let acidTankLevel = (typeof data.ph !== 'undefined' && typeof data.ph.tank !== 'undefined' && typeof data.ph.tank.level !== 'undefined') ? parseInt(data.ph.tank.level, 10) : schem.ph.tank.level;
3067
+ let orpTankLevel = (typeof data.orp !== 'undefined' && typeof data.orp.tank !== 'undefined' && typeof data.orp.tank.level !== 'undefined') ? parseInt(data.orp.tank.level, 10) : schem.orp.tank.level;
3068
3068
  // OCP needs to set the IntelliChem as active so it knows that it exists
3069
3069
  if (sl.enabled && send) {
3070
3070
  if (!schem.isActive) {
@@ -2825,7 +2825,8 @@ class IntelliCenterBodyCommands extends BodyCommands {
2825
2825
  processing: boolean,
2826
2826
  bytes: number[],
2827
2827
  body1: { heatMode: number, heatSetpoint: number, coolSetpoint: number },
2828
- body2: { heatMode: number, heatSetpoint: number, coolSetpoint: number }
2828
+ body2: { heatMode: number, heatSetpoint: number, coolSetpoint: number },
2829
+ _processingStartTime?: number
2829
2830
  };
2830
2831
  private async queueBodyHeatSettings(bodyId?: number, byte?: number, data?: any): Promise<Boolean> {
2831
2832
  logger.debug(`queueBodyHeatSettings: ${JSON.stringify(this.bodyHeatSettings)}`); // remove this line if #848 is fixed
@@ -2837,9 +2838,18 @@ class IntelliCenterBodyCommands extends BodyCommands {
2837
2838
  bytes: [],
2838
2839
  body1: { heatMode: body1.heatMode || 1, heatSetpoint: body1.heatSetpoint || 78, coolSetpoint: body1.coolSetpoint || 100 },
2839
2840
  body2: { heatMode: body2.heatMode || 1, heatSetpoint: body2.heatSetpoint || 78, coolSetpoint: body2.coolSetpoint || 100 }
2840
- }
2841
+ };
2841
2842
  }
2842
2843
  let bhs = this.bodyHeatSettings;
2844
+
2845
+ // Reset processing state if it's been stuck for too long (more than 10 seconds)
2846
+ if (bhs.processing && bhs._processingStartTime && (Date.now() - bhs._processingStartTime > 10000)) {
2847
+ logger.warn(`Resetting stuck bodyHeatSettings processing state after timeout`);
2848
+ bhs.processing = false;
2849
+ bhs.bytes = [];
2850
+ delete bhs._processingStartTime;
2851
+ }
2852
+
2843
2853
  if (typeof data !== 'undefined' && typeof bodyId !== 'undefined' && bodyId > 0) {
2844
2854
  let body = bodyId === 2 ? bhs.body2 : bhs.body1;
2845
2855
  if (!bhs.bytes.includes(byte) && byte) bhs.bytes.push(byte);
@@ -2849,6 +2859,7 @@ class IntelliCenterBodyCommands extends BodyCommands {
2849
2859
  }
2850
2860
  if (!bhs.processing && bhs.bytes.length > 0) {
2851
2861
  bhs.processing = true;
2862
+ bhs._processingStartTime = Date.now();
2852
2863
  let byte2 = bhs.bytes.shift();
2853
2864
  let fnToByte = function (num) { return num < 0 ? Math.abs(num) | 0x80 : Math.abs(num) || 0; };
2854
2865
  let payload = [0, 0, byte2, 1,
@@ -2890,13 +2901,16 @@ class IntelliCenterBodyCommands extends BodyCommands {
2890
2901
  }
2891
2902
  state.emitEquipmentChanges();
2892
2903
  } catch (err) {
2904
+ logger.error(`Error in queueBodyHeatSettings: ${err.message}`);
2893
2905
  bhs.processing = false;
2894
2906
  bhs.bytes = [];
2907
+ delete bhs._processingStartTime;
2895
2908
  throw (err);
2896
2909
  }
2897
2910
  finally {
2898
2911
  bhs.processing = false;
2899
2912
  bhs.bytes = [];
2913
+ delete bhs._processingStartTime;
2900
2914
  }
2901
2915
  return true;
2902
2916
  }
@@ -2912,7 +2926,10 @@ class IntelliCenterBodyCommands extends BodyCommands {
2912
2926
  }
2913
2927
  }, 3000);
2914
2928
  }
2915
- else bhs.processing = false;
2929
+ else {
2930
+ bhs.processing = false;
2931
+ delete bhs._processingStartTime;
2932
+ }
2916
2933
  return true;
2917
2934
  }
2918
2935
  }
@@ -31,6 +31,8 @@ export class SunTouchBoard extends EasyTouchBoard {
31
31
  constructor(system: PoolSystem) {
32
32
  super(system); // graph chain to EasyTouchBoard constructor.
33
33
  this.valueMaps.expansionBoards = new byteValueMap([
34
+ // 33 added per #1108;
35
+ [33, { name: 'stshared', part: '520820', desc: 'Pool and Spa controller', bodies: 2, valves: 4, circuits: 5, single: false, shared: true, dual: false, features: 4, chlorinators: 1, chemControllers: 1 }],
34
36
  [41, { name: 'stshared', part: '520820', desc: 'Pool and Spa controller', bodies: 2, valves: 4, circuits: 5, single: false, shared: true, dual: false, features: 4, chlorinators: 1, chemControllers: 1 }],
35
37
  [40, { name: 'stsingle', part: '520819', desc: 'Pool or Spa controller', bodies: 2, valves: 4, circuits: 5, single: true, shared: true, dual: false, features: 4, chlorinators: 1, chemControllers: 1 }]
36
38
  ]);
@@ -582,7 +582,7 @@ export class byteValueMaps {
582
582
  public valveModes: byteValueMap = new byteValueMap([
583
583
  [0, { name: 'off', desc: 'Off' }],
584
584
  [1, { name: 'pool', desc: 'Pool' }],
585
- [2, { name: 'spa', dest: 'Spa' }],
585
+ [2, { name: 'spa', desc: 'Spa' }],
586
586
  [3, { name: 'spillway', desc: 'Spillway' }],
587
587
  [4, { name: 'spadrain', desc: 'Spa Drain' }]
588
588
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodejs-poolcontroller",
3
- "version": "8.1.1",
3
+ "version": "8.1.2",
4
4
  "description": "nodejs-poolController",
5
5
  "main": "app.js",
6
6
  "author": {