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 +4 -0
- package/config.schema.json +4 -1
- package/index.js +53 -38
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
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
|
|
|
@@ -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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
454
|
+
command = `Y${area_number}`; // Home
|
|
440
455
|
break;
|
|
441
456
|
case Characteristic.SecuritySystemTargetState.AWAY_ARM:
|
|
442
|
-
command =
|
|
457
|
+
command = `A${area_number}`; // Away arm
|
|
443
458
|
break;
|
|
444
459
|
case Characteristic.SecuritySystemTargetState.DISARM:
|
|
445
|
-
command =
|
|
460
|
+
command = `D${area_number}`; // Disarm
|
|
446
461
|
break;
|
|
447
462
|
default:
|
|
448
|
-
this.log.debug(
|
|
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(
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
519
|
+
connection.write(`\\${command}/`, function (err) {
|
|
505
520
|
if (err) {
|
|
506
|
-
platform.log.debug(
|
|
521
|
+
platform.log.debug(`Error writing to connection: ${err}`);
|
|
507
522
|
reject(err);
|
|
508
523
|
} else {
|
|
509
|
-
platform.log.debug(
|
|
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(
|
|
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
|
+
"version": "4.2.6-beta.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Posthumus",
|
|
8
8
|
"email": "chris.posthumus@gmail.com"
|