homebridge-texecom-full 4.2.5 → 4.2.6-beta.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  This change log documents all release versions of homebridge-texecom
4
4
 
5
+ ### 4.2.6-beta.0 (2025-01-21)
6
+
7
+ - **TWEAK** - House keeping.
8
+ - **FIX** - Added carbonmonoxide and dioxide to config.schema.
5
9
 
6
10
  ### 4.2.5 (2025-01-03)
7
11
 
@@ -64,7 +64,10 @@
64
64
  "type": "string",
65
65
  "enum": [
66
66
  "contact",
67
- "motion"
67
+ "motion",
68
+ "smoke",
69
+ "carbonmonoxide",
70
+ "carbondioxide"
68
71
  ],
69
72
  "title": "Zone Type"
70
73
  },
package/index.js CHANGED
@@ -77,11 +77,11 @@ TexecomPlatform.prototype = {
77
77
  // Is the zone active?
78
78
  var zone_active = S(zone_data).endsWith('1');
79
79
 
80
- platform.log.debug("Zone update received for zone " + updated_zone + " active: " + zone_active);
80
+ platform.log.debug(`Zone update received for zone ${updated_zone} active: ${zone_active}`);
81
81
 
82
82
  for (var i = 0; i < zoneCount; i++) {
83
83
  if (zoneAccessories[i].zone_number == updated_zone) {
84
- platform.log.debug("Zone match found, updating zone status in HomeKit to " + zone_active);
84
+ platform.log.debug(`Zone match found, updating zone status in HomeKit to ${zone_active}`);
85
85
  zoneAccessories[i].changeHandler(zone_active);
86
86
 
87
87
  if (zone_active) {
@@ -92,10 +92,10 @@ TexecomPlatform.prototype = {
92
92
 
93
93
  // Set the security system state to "ALARM_TRIGGERED"
94
94
  stateValue = Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED;
95
- platform.log.log("Area " + areaAccessories[a].zone_number + " manual triggered");
95
+ platform.log.log(`Area ${areaAccessories[a].zone_number} manual triggered`);
96
96
 
97
97
  // Log the state change
98
- platform.log.debug("Area match found, updating area status in HomeKit to " + stateValue);
98
+ platform.log.debug(`Area match found, updating area status in HomeKit to ${stateValue}`);
99
99
  setByAlarm = true;
100
100
  areaAccessories[a].changeHandler(stateValue);
101
101
 
@@ -103,7 +103,7 @@ TexecomPlatform.prototype = {
103
103
  });
104
104
  }
105
105
  catch (e) {
106
- console.debug('Error processing zones for area ' + a + '. Please add zones under area.');
106
+ console.debug(`Error processing zones for area ${a} Please add zones under area.`);
107
107
  }
108
108
  }
109
109
  }
@@ -119,14 +119,16 @@ TexecomPlatform.prototype = {
119
119
  var user = S(data).substring(5, 7);
120
120
  var stateValue;
121
121
 
122
+ let armedByUser = user;
123
+
122
124
  switch (String(status)) {
123
125
  case "L":
124
126
  stateValue = Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED;
125
- platform.log.log("Area " + updated_area + " triggered");
127
+ platform.log.log(`Area ${updated_area} triggered`);
126
128
  break;
127
129
  case "D":
128
130
  stateValue = Characteristic.SecuritySystemCurrentState.DISARMED;
129
- platform.log.log("Area " + updated_area + " disarmed");
131
+ platform.log.log(`Area ${updated_area} disarmed by User ${user}`);
130
132
  areas_armed = areas_armed.filter(value => value !== zpad(updated_area, 3));
131
133
  break;
132
134
  case "A":
@@ -137,7 +139,7 @@ TexecomPlatform.prototype = {
137
139
 
138
140
  if (user == "17") {
139
141
  stateValue = Characteristic.SecuritySystemCurrentState.AWAY_ARM;
140
- platform.log.log("Area " + updated_area + " armed");
142
+ platform.log.log(`Area ${updated_area} armed (away) by User ${user}`);
141
143
  }
142
144
  else if (user == "25" || user == "254") {
143
145
  // Read the target state
@@ -158,16 +160,16 @@ TexecomPlatform.prototype = {
158
160
  stateValue = Characteristic.SecuritySystemCurrentState.DISARMED;
159
161
  break;
160
162
  default:
161
- platform.log.error("Unknown target state: " + targetState);
163
+ platform.log.error(`Unknown target state: ${targetState}`);
162
164
  return;
163
165
  }
164
166
 
165
- platform.log.log("User 254: Target state is " + targetState + ", updated stateValue is " + stateValue);
167
+ platform.log.log(`User ${user}: Target state is ${targetState}, updated stateValue is ${stateValue}`);
166
168
 
167
169
  }
168
170
  else {
169
171
  stateValue = Characteristic.SecuritySystemCurrentState.NIGHT_ARM;
170
- platform.log.log("Area " + updated_area + " night armed");
172
+ platform.log.log(`Area ${updated_area} armed (night) by User ${user}`);
171
173
  }
172
174
 
173
175
  if (stateValue == Characteristic.SecuritySystemCurrentState.AWAY_ARM) {
@@ -184,19 +186,19 @@ TexecomPlatform.prototype = {
184
186
  }
185
187
  break;
186
188
  default:
187
- platform.log.log("Unknown status letter " + status);
189
+ platform.log.log(`Unknown status letter ${status}`);
188
190
  return;
189
191
  }
190
192
  for (var i = 0; i < areaCount; i++) {
191
193
  if (areaAccessories[i].zone_number == updated_area) {
192
- platform.log.debug("Area match found, updating area status in HomeKit to " + stateValue);
194
+ platform.log.debug(`Area match found, updating area status in HomeKit to ${stateValue}`);
193
195
  setByAlarm = true;
194
- areaAccessories[i].changeHandler(stateValue);
196
+ areaAccessories[i].changeHandler(stateValue, armedByUser);
195
197
  break;
196
198
  }
197
199
  }
198
200
  } else {
199
- platform.log.debug("Unknown string from Texecom: " + S(data));
201
+ platform.log.debug(`Unknown string from Texecom: ${S(data)}`);
200
202
  }
201
203
  }
202
204
 
@@ -211,7 +213,7 @@ TexecomPlatform.prototype = {
211
213
  serialPort.on("open", function () {
212
214
  platform.log.log("Serial port opened");
213
215
  serialPort.on('data', function (data) {
214
- platform.log.debug("Serial data received: " + data);
216
+ platform.log.debug(`Serial data received: ${data}`);
215
217
  responseEmitter.emit('data', data);
216
218
  processData(data);
217
219
  });
@@ -228,7 +230,7 @@ TexecomPlatform.prototype = {
228
230
  connection.setNoDelay(true);
229
231
 
230
232
  connection.on('data', function (data) {
231
- platform.log.debug("IP data received: " + data);
233
+ platform.log.debug(`IP data received: ${data}`);
232
234
  responseEmitter.emit('data', data);
233
235
  processData(data);
234
236
  });
@@ -283,7 +285,7 @@ function TexecomAccessory(log, config) {
283
285
  shasum.update(this.zone_number/* || this.area_number*/);
284
286
 
285
287
  this.sn = shasum.digest('base64');
286
- log.log('Computed SN: ' + this.sn);
288
+ log.log(`Computed SN: ${this.sn}`);
287
289
  }
288
290
  }
289
291
 
@@ -300,7 +302,7 @@ TexecomAccessory.prototype = {
300
302
  informationService
301
303
  .setCharacteristic(Characteristic.Name, this.name)
302
304
  .setCharacteristic(Characteristic.Manufacturer, "Homebridge")
303
- .setCharacteristic(Characteristic.Model, "Texecom " + (this.accessoryType === "zone" ? "Zone" : "Area"))
305
+ .setCharacteristic(Characteristic.Model, `Texecom ${(this.accessoryType === "zone" ? "Zone" : "Area")}`)
304
306
  .setCharacteristic(Characteristic.SerialNumber, this.sn);
305
307
 
306
308
 
@@ -333,10 +335,18 @@ TexecomAccessory.prototype = {
333
335
  .setValue(newState ? Characteristic.CarbonMonoxideDetected.CO_LEVELS_ABNORMAL : Characteristic.CarbonMonoxideDetected.CO_LEVELS_NORMAL);
334
336
  };
335
337
  break;
338
+ case "carbondioxide":
339
+ service = new Service.CarbonDioxideSensor();
340
+ changeAction = function (newState) {
341
+ service.getCharacteristic(Characteristic.CarbonDioxideDetected)
342
+ .setValue(newState ? Characteristic.CarbonDioxideDetected.CO_LEVELS_ABNORMAL : Characteristic.CarbonDioxideDetected.CO_LEVELS_NORMAL);
343
+ };
344
+ break;
336
345
 
337
346
  case "securitysystem":
338
347
  service = new Service.SecuritySystem();
339
- changeAction = function (newState) {
348
+
349
+ changeAction = function (newState, user = "unknown") {
340
350
  var targetState;
341
351
  switch (newState) {
342
352
  case Characteristic.SecuritySystemCurrentState.NIGHT_ARM:
@@ -362,7 +372,7 @@ TexecomAccessory.prototype = {
362
372
  service.getCharacteristic(Characteristic.SecuritySystemTargetState).updateValue(targetState);
363
373
  }
364
374
  service.getCharacteristic(Characteristic.SecuritySystemCurrentState).updateValue(newState);
365
- me.log.debug("Set target state " + targetState + " and current state " + newState + " in response to notification from alarm");
375
+ me.log.debug(`Set target state ${targetState} and current state ${newState} in response to notification from alarm`);
366
376
  };
367
377
 
368
378
  // we don't know the alarm's state at startup, safer to assume disarmed:
@@ -372,7 +382,7 @@ TexecomAccessory.prototype = {
372
382
  service.getCharacteristic(Characteristic.SecuritySystemTargetState)
373
383
  .on('set', function (value, callback) {
374
384
  if (setByAlarm) {
375
- platform.log.debug("Not sending command to alarm for change to state " + value + " because the state change appears to have come from the alarm itself.");
385
+ platform.log.debug(`Not sending command to alarm for change to state ${value} because the state change appears to have come from the alarm itself.`);
376
386
  setByAlarm = false;
377
387
  return;
378
388
  }
@@ -395,9 +405,9 @@ TexecomAccessory.prototype = {
395
405
  break;
396
406
  }
397
407
 
398
- this.changeHandler = function (status) {
408
+ this.changeHandler = function (status, user = "unknown") {
399
409
  var newState = status;
400
- platform.log.debug("Dwell = " + this.dwell_time);
410
+ platform.log.debug(`Dwell = ${this.dwell_time}`);
401
411
 
402
412
  if (!newState && this.dwell_time > 0) {
403
413
  this.dwell_timer = setTimeout(function () { changeAction(newState); }.bind(this), this.dwell_time);
@@ -408,7 +418,12 @@ TexecomAccessory.prototype = {
408
418
  changeAction(newState);
409
419
  }
410
420
 
411
- platform.log.debug("Changing state with changeHandler to " + newState);
421
+ if (user == "unknown") {
422
+ platform.log.debug(`Changing state with changeHandler to ${newState}`);
423
+ }
424
+ else {
425
+ platform.log.debug(`Changing state with changeHandler to ${newState} by User ${user}`);
426
+ }
412
427
 
413
428
  }.bind(this);
414
429
 
@@ -436,26 +451,26 @@ function areaTargetSecurityStateSet(platform, accessory, service, value, callbac
436
451
  switch (value) {
437
452
  case Characteristic.SecuritySystemTargetState.NIGHT_ARM:
438
453
  case Characteristic.SecuritySystemTargetState.STAY_ARM:
439
- command = "Y" + area_number; // Home
454
+ command = `Y${area_number}`; // Home
440
455
  break;
441
456
  case Characteristic.SecuritySystemTargetState.AWAY_ARM:
442
- command = "A" + area_number; // Away arm
457
+ command = `A${area_number}`; // Away arm
443
458
  break;
444
459
  case Characteristic.SecuritySystemTargetState.DISARM:
445
- command = "D" + area_number; // Disarm
460
+ command = `D${area_number}`; // Disarm
446
461
  break;
447
462
  default:
448
- this.log.debug("Unknown target state: " + value);
463
+ this.log.debug(`Unknown target state: ${value}`);
449
464
  callback(new Error("Unknown target state"));
450
465
  return;
451
466
  }
452
467
 
453
- platform.log.debug("Sending arm/disarm command " + value + " to area " + accessory.zone_number);
468
+ platform.log.debug(`Sending arm/disarm command ${value} to area ${accessory.zone_number}`);
454
469
 
455
470
 
456
471
 
457
472
 
458
- writeCommandAndWaitForOK(platform.texecomConnection, "W" + platform.udl)
473
+ writeCommandAndWaitForOK(platform.texecomConnection, `W${platform.udl}`)
459
474
  .then(() => writeCommandAndWaitForOK(platform.texecomConnection, command, 0))
460
475
  .then(() => {
461
476
  // OK response from alarm is only indication that the target state has been reached
@@ -474,18 +489,18 @@ function areaTargetSecurityStateSet(platform, accessory, service, value, callbac
474
489
  currentState = Characteristic.SecuritySystemCurrentState.DISARMED;
475
490
  break;
476
491
  default:
477
- platform.log.debug("Unknown target alarm state " + value);
492
+ platform.log.debug(`Unknown target alarm state ${value}`);
478
493
  callback(new Error("Unknown target state"));
479
494
  return;
480
495
  }
481
- platform.log.debug("Setting current status of area " + accessory.zone_number + " to " + currentState + " because alarm responded OK");
496
+ platform.log.debug(`Setting current status of area ${accessory.zone_number} to ${currentState} because alarm responded OK`);
482
497
  service.getCharacteristic(Characteristic.SecuritySystemCurrentState)
483
498
  .updateValue(currentState);
484
499
  accessory.target_State = currentState;
485
500
  callback();
486
501
  })
487
502
  .catch((err) => {
488
- platform.log.debug("Callback with error " + err);
503
+ platform.log.debug(`Callback with error ${err}`);
489
504
  callback(err); // Handle errors
490
505
  });
491
506
  }
@@ -501,19 +516,19 @@ function writeCommandAndWaitForOK(connection, command, retryCount = 1) {
501
516
 
502
517
  responseEmitter.on('data', handleData);
503
518
 
504
- connection.write("\\" + command + "/", function (err) {
519
+ connection.write(`\\${command}/`, function (err) {
505
520
  if (err) {
506
- platform.log.debug("Error writing to connection: " + err);
521
+ platform.log.debug(`Error writing to connection: ${err}`);
507
522
  reject(err);
508
523
  } else {
509
- platform.log.debug("Command sent: " + command);
524
+ platform.log.debug(`Command sent: ${command}`);
510
525
  }
511
526
  });
512
527
 
513
528
  setTimeout(() => {
514
529
  responseEmitter.removeListener('data', handleData);
515
530
  if (retryCount > 0) {
516
- platform.log.debug("Retrying command due to timeout, retries left: " + retryCount);
531
+ platform.log.debug(`Retrying command due to timeout, retries left: ${retryCount}`);
517
532
  writeCommandAndWaitForOK(connection, command, retryCount - 1).then(resolve).catch(reject);
518
533
  } else {
519
534
  reject(new Error("Timeout after retries"));
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "displayName": "Homebridge Texecom",
3
3
  "name": "homebridge-texecom-full",
4
4
  "description": "A plugin for homebridge to integrate Texecom Premier Elite alarm systems into HomeKit",
5
- "version": "4.2.5",
5
+ "version": "4.2.6-beta.0",
6
6
  "author": {
7
7
  "name": "Chris Posthumus",
8
8
  "email": "chris.posthumus@gmail.com"