homebridge-smartsystem 6.3.2 → 6.3.3

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
@@ -279,6 +279,7 @@ Homebridge UI version
279
279
  ### v6.3.x - 23-09-2022 - Shelly PM release
280
280
  - 1: first test 1 PM
281
281
  - 2: logging now more according to debug true/false in the config file
282
+ - 3: power bindings now when: 5% change < 1000W, 2% change > 1000W
282
283
 
283
284
 
284
285
  ## Hardware
package/config.json CHANGED
@@ -380,6 +380,54 @@
380
380
  }
381
381
  ],
382
382
  "cunits": [
383
+ {
384
+ "logicalNodeAddress": 252,
385
+ "logicalAddress": 102,
386
+ "masterAddress": "192.168.0.97",
387
+ "masterPort": 5001,
388
+ "name": "<Solar Panels",
389
+ "displayName": "<Solar Panels",
390
+ "extendedType": 0,
391
+ "active": "N",
392
+ "used": "Y",
393
+ "group": 0
394
+ },
395
+ {
396
+ "logicalNodeAddress": 252,
397
+ "logicalAddress": 103,
398
+ "masterAddress": "192.168.0.97",
399
+ "masterPort": 5001,
400
+ "name": ">Cars",
401
+ "displayName": ">Cars",
402
+ "extendedType": 0,
403
+ "active": "N",
404
+ "used": "Y",
405
+ "group": 0
406
+ },
407
+ {
408
+ "logicalNodeAddress": 252,
409
+ "logicalAddress": 100,
410
+ "masterAddress": "192.168.0.97",
411
+ "masterPort": 5001,
412
+ "name": ">Grid",
413
+ "displayName": ">Grid",
414
+ "extendedType": 0,
415
+ "active": "N",
416
+ "used": "Y",
417
+ "group": 0
418
+ },
419
+ {
420
+ "logicalNodeAddress": 252,
421
+ "logicalAddress": 101,
422
+ "masterAddress": "192.168.0.97",
423
+ "masterPort": 5001,
424
+ "name": ">Swimmingpool",
425
+ "displayName": ">Swimmingpool",
426
+ "extendedType": 0,
427
+ "active": "N",
428
+ "used": "Y",
429
+ "group": 0
430
+ },
383
431
  {
384
432
  "logicalNodeAddress": 3,
385
433
  "logicalAddress": 4,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-smartsystem",
3
3
  "displayname": "Duotecno Bridge",
4
- "version": "6.3.2",
4
+ "version": "6.3.3",
5
5
  "description": "SmartServer (Proxy Websockets to TCP sockets, Smappee MQTT, Duotecno IP Nodes, Homekit interface)",
6
6
  "main": "index.js",
7
7
  "author": "Johan Coppieters",
@@ -94,22 +94,40 @@ class PowerBase extends base_1.Base {
94
94
  //////////////////////////////////////////////
95
95
  // Bindings to Duotecno virtual temp sensor //
96
96
  //////////////////////////////////////////////
97
+ significant(current, previous) {
98
+ // no values yet -> don't update
99
+ if (isNaN(current))
100
+ return false;
101
+ // no previous value -> always update
102
+ if (isNaN(previous))
103
+ return true;
104
+ // less than 1000W -> update on: difference > 5% previous
105
+ if (current < 1000)
106
+ return Math.abs(previous - current) > (previous * 0.05);
107
+ // more than 1000W -> update on: difference > 2% previous
108
+ if (current >= 1000)
109
+ return Math.abs(previous - current) > (previous * 0.02);
110
+ return false;
111
+ }
97
112
  applyBindings() {
98
113
  if (this.realtimeCounter % 2 === 0) {
99
114
  // for all bindings
100
115
  this.bindings.forEach(b => {
101
116
  const power = this.evalPower(b.channel);
102
- if ((!isNaN(power)) && (isNaN(b.power) || (Math.abs(b.power - power) > Math.abs(b.power * kPercentChange)))) {
103
- (0, logger_1.debug)("power", "APPLY to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name + " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) + " > threshold: " + Math.abs(b.power * kPercentChange));
117
+ if (this.significant(power, b.power)) {
118
+ (0, logger_1.debug)("power", "APPLY to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
119
+ " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
120
+ " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
104
121
  this.applyBinding(b, power)
105
122
  .then(value => {
106
123
  b.power = value;
107
- // debug("homebridge", "set unit " + b.name + " to " + value);
124
+ // debug("power", "set unit " + b.name + " to " + value);
108
125
  })
109
126
  .catch((e) => (0, logger_1.err)(this.type, e.message || e));
110
- }
111
- else {
112
- (0, logger_1.debug)("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name + " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) + " > threshold: " + Math.abs(b.power * kPercentChange));
127
+ // } else {
128
+ // debug("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
129
+ // " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
130
+ // " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
113
131
  }
114
132
  });
115
133
  }
@@ -122,8 +140,8 @@ class PowerBase extends base_1.Base {
122
140
  yield unit.setSensorValue(Math.abs(value));
123
141
  return value;
124
142
  }
125
- else {
126
- throw new Error("***** UNIT NOT FOUND for binding (" + value + ") " + binding.masterAddress + " - " + binding.logicalNodeAddress + ";" + binding.logicalAddress + " *****");
143
+ else if ((binding.logicalNodeAddress != 0) || (binding.logicalAddress != 0)) {
144
+ throw new Error("***** UNIT NOT FOUND for binding value " + value + " to " + binding.masterAddress + " - " + binding.logicalNodeAddress + ";" + binding.logicalAddress + " *****");
127
145
  }
128
146
  });
129
147
  }
@@ -144,7 +162,6 @@ class PowerBase extends base_1.Base {
144
162
  if (rule.type === "power") {
145
163
  // add all channels this rule refers to
146
164
  power = this.evalPower(rule.channel);
147
- // power = rule.channel.split("+").reduce((acc, cur) => acc + this.channels[parseInt(cur)]?.power ?? 0, 0);
148
165
  }
149
166
  else if (rule.type === "sun") {
150
167
  // calc fake power usage
@@ -191,10 +208,12 @@ class PowerBase extends base_1.Base {
191
208
  applyCommand(action) {
192
209
  return __awaiter(this, void 0, void 0, function* () {
193
210
  const unit = this.system.findUnit(this.system.findMaster(action.masterAddress, action.masterPort), action.logicalNodeAddress, action.logicalAddress);
194
- if (unit)
211
+ if (unit) {
195
212
  yield unit.setState(action.value);
196
- else
197
- throw new Error("***** UNIT NOT FOUND for action (" + action.value + ") " + action.masterAddress + " - " + action.logicalNodeAddress + ";" + action.logicalAddress + " *****");
213
+ }
214
+ else if ((action.logicalNodeAddress != 0) || (action.logicalAddress != 0)) {
215
+ throw new Error("***** UNIT NOT FOUND for action for value " + action.value + " to " + action.masterAddress + " - " + action.logicalNodeAddress + ";" + action.logicalAddress + " *****");
216
+ }
198
217
  });
199
218
  }
200
219
  //
@@ -111,36 +111,61 @@ export class PowerBase extends Base {
111
111
  //////////////////////////////////////////////
112
112
  // Bindings to Duotecno virtual temp sensor //
113
113
  //////////////////////////////////////////////
114
+ significant(current: number, previous: number): boolean {
115
+ // no values yet -> don't update
116
+ if (isNaN(current))
117
+ return false;
118
+
119
+ // no previous value -> always update
120
+ if (isNaN(previous))
121
+ return true;
122
+
123
+ // less than 1000W -> update on: difference > 5% previous
124
+ if (current < 1000)
125
+ return Math.abs(previous - current) > (previous * 0.05);
126
+
127
+ // more than 1000W -> update on: difference > 2% previous
128
+ if (current >= 1000)
129
+ return Math.abs(previous - current) > (previous * 0.02);
130
+
131
+ return false;
132
+ }
133
+
114
134
  applyBindings() {
115
135
  if (this.realtimeCounter % 2 === 0) {
116
136
  // for all bindings
117
137
  this.bindings.forEach( b => {
118
138
  const power = this.evalPower(b.channel);
119
- if ((!isNaN(power)) && (isNaN(b.power) || (Math.abs(b.power - power) > Math.abs(b.power * kPercentChange)))) {
120
- debug("power", "APPLY to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name + " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) + " > threshold: " + Math.abs(b.power * kPercentChange))
139
+ if (this.significant(power, b.power)) {
140
+ debug("power", "APPLY to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
141
+ " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
142
+ " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
121
143
  this.applyBinding(b, power)
122
144
  .then(value => {
123
145
  b.power = value;
124
- // debug("homebridge", "set unit " + b.name + " to " + value);
146
+ // debug("power", "set unit " + b.name + " to " + value);
125
147
  })
126
148
  .catch((e) => err(this.type, e.message || e));
127
149
 
128
- } else {
129
- debug("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name + " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) + " > threshold: " + Math.abs(b.power * kPercentChange))
150
+ // } else {
151
+ // debug("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
152
+ // " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
153
+ // " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
130
154
  }
131
155
  });
132
156
  }
133
157
  }
134
158
 
135
159
  async applyBinding(binding: Binding, value: number): Promise<number> {
136
- const unit = this.system.findUnit(this.system.findMaster(binding.masterAddress, binding.masterPort), binding.logicalNodeAddress, binding.logicalAddress);
160
+ const unit = this.system.findUnit(this.system.findMaster(binding.masterAddress, binding.masterPort),
161
+ binding.logicalNodeAddress, binding.logicalAddress);
137
162
  if (unit) {
138
163
  if (!isNaN(value))
139
164
  await unit.setSensorValue(Math.abs(value));
140
165
  return value;
141
166
 
142
- } else {
143
- throw new Error("***** UNIT NOT FOUND for binding (" + value + ") " + binding.masterAddress + " - " + binding.logicalNodeAddress + ";" + binding.logicalAddress + " *****");
167
+ } else if ((binding.logicalNodeAddress != 0) || (binding.logicalAddress != 0)) {
168
+ throw new Error("***** UNIT NOT FOUND for binding value " + value + " to " + binding.masterAddress + " - " + binding.logicalNodeAddress + ";" + binding.logicalAddress + " *****");
144
169
  }
145
170
  }
146
171
 
@@ -151,8 +176,8 @@ export class PowerBase extends Base {
151
176
  applyRules() {
152
177
  if (this.realtimeCounter % 60 === 0) {
153
178
  log("power", this.type + " > RealTime totals: Power = " + this.realtime.totalPower +
154
- ", Export = " + this.realtime.totalExportEnergy +
155
- ", Import = " + this.realtime.totalImportEnergy);
179
+ ", Export = " + this.realtime.totalExportEnergy +
180
+ ", Import = " + this.realtime.totalImportEnergy);
156
181
  }
157
182
 
158
183
  if (this.realtimeCounter % 5 === 0) {
@@ -164,7 +189,6 @@ export class PowerBase extends Base {
164
189
  if (rule.type === "power") {
165
190
  // add all channels this rule refers to
166
191
  power = this.evalPower(rule.channel);
167
- // power = rule.channel.split("+").reduce((acc, cur) => acc + this.channels[parseInt(cur)]?.power ?? 0, 0);
168
192
 
169
193
  } else if (rule.type === "sun") {
170
194
  // calc fake power usage
@@ -201,11 +225,12 @@ export class PowerBase extends Base {
201
225
  rule.current = newCurrent;
202
226
  if (newCurrent < rule.actions.length) {
203
227
  this.applyCommand(rule.actions[newCurrent])
204
- .then((val) => {debug("power", "## sent command -> " + rule.type +
205
- ", power = " + power + ", channel = " + rule.channel +
206
- " -> current = " + newCurrent +
207
- " (unit: " + rule.actions[newCurrent].name + ", value: " + rule.actions[newCurrent].value + ")");
208
- rule.current = newCurrent;})
228
+ .then((val) => { debug("power", "## sent command -> " + rule.type +
229
+ ", power = " + power + ", channel = " + rule.channel +
230
+ " -> current = " + newCurrent +
231
+ " (unit: " + rule.actions[newCurrent].name + ", value: " + rule.actions[newCurrent].value + ")");
232
+ rule.current = newCurrent;
233
+ })
209
234
  .catch((e) => err(this.type, e.message));
210
235
  }
211
236
  }
@@ -213,10 +238,12 @@ export class PowerBase extends Base {
213
238
 
214
239
  async applyCommand(action: Action) {
215
240
  const unit = this.system.findUnit(this.system.findMaster(action.masterAddress, action.masterPort), action.logicalNodeAddress, action.logicalAddress);
216
- if (unit)
241
+ if (unit) {
217
242
  await unit.setState(action.value);
218
- else
219
- throw new Error("***** UNIT NOT FOUND for action (" + action.value + ") " + action.masterAddress + " - " + action.logicalNodeAddress + ";" + action.logicalAddress + " *****");
243
+
244
+ } else if ((action.logicalNodeAddress != 0) || (action.logicalAddress != 0)) {
245
+ throw new Error("***** UNIT NOT FOUND for action for value " + action.value + " to " + action.masterAddress + " - " + action.logicalNodeAddress + ";" + action.logicalAddress + " *****");
246
+ }
220
247
  }
221
248
 
222
249
  //