homebridge-texecom-full 4.2.5 → 4.2.6-beta.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/CHANGELOG.md +8 -0
- package/config.schema.json +3 -1
- package/index.js +46 -38
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This change log documents all release versions of homebridge-texecom
|
|
4
4
|
|
|
5
|
+
### 4.2.6-beta.2 (2025-01-22)
|
|
6
|
+
|
|
7
|
+
- **FIX** - Removed carbondioxide
|
|
8
|
+
|
|
9
|
+
### 4.2.6-beta.0 (2025-01-21)
|
|
10
|
+
|
|
11
|
+
- **TWEAK** - House keeping.
|
|
12
|
+
- **FIX** - Added carbonmonoxide and dioxide to config.schema.
|
|
5
13
|
|
|
6
14
|
### 4.2.5 (2025-01-03)
|
|
7
15
|
|
package/config.schema.json
CHANGED
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(
|
|
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(
|
|
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(
|
|
95
|
+
platform.log.log(`Area ${areaAccessories[a].zone_number} manual triggered`);
|
|
96
96
|
|
|
97
97
|
// Log the state change
|
|
98
|
-
platform.log.debug(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
163
|
+
platform.log.error(`Unknown target state: ${targetState}`);
|
|
162
164
|
return;
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
platform.log.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
305
|
+
.setCharacteristic(Characteristic.Model, `Texecom ${(this.accessoryType === "zone" ? "Zone" : "Area")}`)
|
|
304
306
|
.setCharacteristic(Characteristic.SerialNumber, this.sn);
|
|
305
307
|
|
|
306
308
|
|
|
@@ -336,7 +338,8 @@ TexecomAccessory.prototype = {
|
|
|
336
338
|
|
|
337
339
|
case "securitysystem":
|
|
338
340
|
service = new Service.SecuritySystem();
|
|
339
|
-
|
|
341
|
+
|
|
342
|
+
changeAction = function (newState, user = "unknown") {
|
|
340
343
|
var targetState;
|
|
341
344
|
switch (newState) {
|
|
342
345
|
case Characteristic.SecuritySystemCurrentState.NIGHT_ARM:
|
|
@@ -362,7 +365,7 @@ TexecomAccessory.prototype = {
|
|
|
362
365
|
service.getCharacteristic(Characteristic.SecuritySystemTargetState).updateValue(targetState);
|
|
363
366
|
}
|
|
364
367
|
service.getCharacteristic(Characteristic.SecuritySystemCurrentState).updateValue(newState);
|
|
365
|
-
me.log.debug(
|
|
368
|
+
me.log.debug(`Set target state ${targetState} and current state ${newState} in response to notification from alarm`);
|
|
366
369
|
};
|
|
367
370
|
|
|
368
371
|
// we don't know the alarm's state at startup, safer to assume disarmed:
|
|
@@ -372,7 +375,7 @@ TexecomAccessory.prototype = {
|
|
|
372
375
|
service.getCharacteristic(Characteristic.SecuritySystemTargetState)
|
|
373
376
|
.on('set', function (value, callback) {
|
|
374
377
|
if (setByAlarm) {
|
|
375
|
-
platform.log.debug(
|
|
378
|
+
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
379
|
setByAlarm = false;
|
|
377
380
|
return;
|
|
378
381
|
}
|
|
@@ -395,9 +398,9 @@ TexecomAccessory.prototype = {
|
|
|
395
398
|
break;
|
|
396
399
|
}
|
|
397
400
|
|
|
398
|
-
this.changeHandler = function (status) {
|
|
401
|
+
this.changeHandler = function (status, user = "unknown") {
|
|
399
402
|
var newState = status;
|
|
400
|
-
platform.log.debug(
|
|
403
|
+
platform.log.debug(`Dwell = ${this.dwell_time}`);
|
|
401
404
|
|
|
402
405
|
if (!newState && this.dwell_time > 0) {
|
|
403
406
|
this.dwell_timer = setTimeout(function () { changeAction(newState); }.bind(this), this.dwell_time);
|
|
@@ -408,7 +411,12 @@ TexecomAccessory.prototype = {
|
|
|
408
411
|
changeAction(newState);
|
|
409
412
|
}
|
|
410
413
|
|
|
411
|
-
|
|
414
|
+
if (user == "unknown") {
|
|
415
|
+
platform.log.debug(`Changing state with changeHandler to ${newState}`);
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
platform.log.debug(`Changing state with changeHandler to ${newState} by User ${user}`);
|
|
419
|
+
}
|
|
412
420
|
|
|
413
421
|
}.bind(this);
|
|
414
422
|
|
|
@@ -436,26 +444,26 @@ function areaTargetSecurityStateSet(platform, accessory, service, value, callbac
|
|
|
436
444
|
switch (value) {
|
|
437
445
|
case Characteristic.SecuritySystemTargetState.NIGHT_ARM:
|
|
438
446
|
case Characteristic.SecuritySystemTargetState.STAY_ARM:
|
|
439
|
-
command =
|
|
447
|
+
command = `Y${area_number}`; // Home
|
|
440
448
|
break;
|
|
441
449
|
case Characteristic.SecuritySystemTargetState.AWAY_ARM:
|
|
442
|
-
command =
|
|
450
|
+
command = `A${area_number}`; // Away arm
|
|
443
451
|
break;
|
|
444
452
|
case Characteristic.SecuritySystemTargetState.DISARM:
|
|
445
|
-
command =
|
|
453
|
+
command = `D${area_number}`; // Disarm
|
|
446
454
|
break;
|
|
447
455
|
default:
|
|
448
|
-
this.log.debug(
|
|
456
|
+
this.log.debug(`Unknown target state: ${value}`);
|
|
449
457
|
callback(new Error("Unknown target state"));
|
|
450
458
|
return;
|
|
451
459
|
}
|
|
452
460
|
|
|
453
|
-
platform.log.debug(
|
|
461
|
+
platform.log.debug(`Sending arm/disarm command ${value} to area ${accessory.zone_number}`);
|
|
454
462
|
|
|
455
463
|
|
|
456
464
|
|
|
457
465
|
|
|
458
|
-
writeCommandAndWaitForOK(platform.texecomConnection,
|
|
466
|
+
writeCommandAndWaitForOK(platform.texecomConnection, `W${platform.udl}`)
|
|
459
467
|
.then(() => writeCommandAndWaitForOK(platform.texecomConnection, command, 0))
|
|
460
468
|
.then(() => {
|
|
461
469
|
// OK response from alarm is only indication that the target state has been reached
|
|
@@ -474,18 +482,18 @@ function areaTargetSecurityStateSet(platform, accessory, service, value, callbac
|
|
|
474
482
|
currentState = Characteristic.SecuritySystemCurrentState.DISARMED;
|
|
475
483
|
break;
|
|
476
484
|
default:
|
|
477
|
-
platform.log.debug(
|
|
485
|
+
platform.log.debug(`Unknown target alarm state ${value}`);
|
|
478
486
|
callback(new Error("Unknown target state"));
|
|
479
487
|
return;
|
|
480
488
|
}
|
|
481
|
-
platform.log.debug(
|
|
489
|
+
platform.log.debug(`Setting current status of area ${accessory.zone_number} to ${currentState} because alarm responded OK`);
|
|
482
490
|
service.getCharacteristic(Characteristic.SecuritySystemCurrentState)
|
|
483
491
|
.updateValue(currentState);
|
|
484
492
|
accessory.target_State = currentState;
|
|
485
493
|
callback();
|
|
486
494
|
})
|
|
487
495
|
.catch((err) => {
|
|
488
|
-
platform.log.debug(
|
|
496
|
+
platform.log.debug(`Callback with error ${err}`);
|
|
489
497
|
callback(err); // Handle errors
|
|
490
498
|
});
|
|
491
499
|
}
|
|
@@ -501,19 +509,19 @@ function writeCommandAndWaitForOK(connection, command, retryCount = 1) {
|
|
|
501
509
|
|
|
502
510
|
responseEmitter.on('data', handleData);
|
|
503
511
|
|
|
504
|
-
connection.write(
|
|
512
|
+
connection.write(`\\${command}/`, function (err) {
|
|
505
513
|
if (err) {
|
|
506
|
-
platform.log.debug(
|
|
514
|
+
platform.log.debug(`Error writing to connection: ${err}`);
|
|
507
515
|
reject(err);
|
|
508
516
|
} else {
|
|
509
|
-
platform.log.debug(
|
|
517
|
+
platform.log.debug(`Command sent: ${command}`);
|
|
510
518
|
}
|
|
511
519
|
});
|
|
512
520
|
|
|
513
521
|
setTimeout(() => {
|
|
514
522
|
responseEmitter.removeListener('data', handleData);
|
|
515
523
|
if (retryCount > 0) {
|
|
516
|
-
platform.log.debug(
|
|
524
|
+
platform.log.debug(`Retrying command due to timeout, retries left: ${retryCount}`);
|
|
517
525
|
writeCommandAndWaitForOK(connection, command, retryCount - 1).then(resolve).catch(reject);
|
|
518
526
|
} else {
|
|
519
527
|
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
|
+
"version": "4.2.6-beta.2",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Posthumus",
|
|
8
8
|
"email": "chris.posthumus@gmail.com"
|