@rfranzoi/scrypted-mqtt-securitysystem 1.0.33 → 1.0.35
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/dist/main.nodejs.js +81 -103
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
package/dist/main.nodejs.js
CHANGED
|
@@ -34024,46 +34024,30 @@ function socketOnError() {
|
|
|
34024
34024
|
|
|
34025
34025
|
"use strict";
|
|
34026
34026
|
|
|
34027
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
34028
|
-
if (k2 === undefined) k2 = k;
|
|
34029
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
34030
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
34031
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34032
|
-
}
|
|
34033
|
-
Object.defineProperty(o, k2, desc);
|
|
34034
|
-
}) : (function(o, m, k, k2) {
|
|
34035
|
-
if (k2 === undefined) k2 = k;
|
|
34036
|
-
o[k2] = m[k];
|
|
34037
|
-
}));
|
|
34038
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34039
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34040
|
-
}) : function(o, v) {
|
|
34041
|
-
o["default"] = v;
|
|
34042
|
-
});
|
|
34043
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
34044
|
-
var ownKeys = function(o) {
|
|
34045
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34046
|
-
var ar = [];
|
|
34047
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34048
|
-
return ar;
|
|
34049
|
-
};
|
|
34050
|
-
return ownKeys(o);
|
|
34051
|
-
};
|
|
34052
|
-
return function (mod) {
|
|
34053
|
-
if (mod && mod.__esModule) return mod;
|
|
34054
|
-
var result = {};
|
|
34055
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34056
|
-
__setModuleDefault(result, mod);
|
|
34057
|
-
return result;
|
|
34058
|
-
};
|
|
34059
|
-
})();
|
|
34060
34027
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
34061
34028
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34062
34029
|
};
|
|
34063
34030
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
34064
|
-
|
|
34031
|
+
// --- Silence ONLY the optional sdk.json warning from @scrypted/sdk ---
|
|
34032
|
+
const __origConsoleError = console.error.bind(console);
|
|
34033
|
+
console.error = (...args) => {
|
|
34034
|
+
const first = args?.[0];
|
|
34035
|
+
const msg = typeof first === 'string' ? first : (first?.message || '');
|
|
34036
|
+
if (typeof msg === 'string' && msg.includes('failed to load custom interface descriptors')) {
|
|
34037
|
+
// swallow just this warning
|
|
34038
|
+
return;
|
|
34039
|
+
}
|
|
34040
|
+
__origConsoleError(...args);
|
|
34041
|
+
};
|
|
34042
|
+
// Carica lo SDK (non tipizziamo qui per non perdere le proprietà runtime)
|
|
34043
|
+
const sdk = __webpack_require__(/*! @scrypted/sdk */ "./node_modules/@scrypted/sdk/dist/src/index.js");
|
|
34044
|
+
// Valori runtime (enum/classi/manager) dal modulo SDK
|
|
34045
|
+
const { ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, // valore (enum)
|
|
34046
|
+
SecuritySystemMode, // valore (enum)
|
|
34047
|
+
systemManager,
|
|
34048
|
+
// ⚠️ NON destrutturare deviceManager: va letto sempre "al volo" da sdk.deviceManager.
|
|
34049
|
+
} = sdk;
|
|
34065
34050
|
const mqtt_1 = __importDefault(__webpack_require__(/*! mqtt */ "./node_modules/mqtt/build/index.js"));
|
|
34066
|
-
const { systemManager, deviceManager } = sdk_1.default;
|
|
34067
34051
|
/** utils */
|
|
34068
34052
|
function truthy(v) {
|
|
34069
34053
|
if (!v)
|
|
@@ -34083,12 +34067,13 @@ function normalize(s) {
|
|
|
34083
34067
|
function clamp(n, min, max) {
|
|
34084
34068
|
return Math.max(min, Math.min(max, n));
|
|
34085
34069
|
}
|
|
34086
|
-
/** SecuritySystem outgoing defaults (PAI-like)
|
|
34070
|
+
/** SecuritySystem outgoing defaults (PAI-like)
|
|
34071
|
+
* Nota: usare number come chiave evita stranezze con gli enum in TS. */
|
|
34087
34072
|
const DEFAULT_OUTGOING = {
|
|
34088
|
-
[
|
|
34089
|
-
[
|
|
34090
|
-
[
|
|
34091
|
-
[
|
|
34073
|
+
[SecuritySystemMode.Disarmed]: 'disarm',
|
|
34074
|
+
[SecuritySystemMode.HomeArmed]: 'arm_home',
|
|
34075
|
+
[SecuritySystemMode.AwayArmed]: 'arm_away',
|
|
34076
|
+
[SecuritySystemMode.NightArmed]: 'arm_night',
|
|
34092
34077
|
};
|
|
34093
34078
|
/** Parse incoming payload -> final mode (ignore transition states) */
|
|
34094
34079
|
function payloadToMode(payload) {
|
|
@@ -34096,23 +34081,22 @@ function payloadToMode(payload) {
|
|
|
34096
34081
|
return;
|
|
34097
34082
|
const p = normalize(payload.toString());
|
|
34098
34083
|
if (['disarm', 'disarmed', 'off', '0', 'idle', 'ready'].includes(p))
|
|
34099
|
-
return
|
|
34084
|
+
return SecuritySystemMode.Disarmed;
|
|
34100
34085
|
if (['arm_home', 'home', 'stay', 'armed_home'].includes(p))
|
|
34101
|
-
return
|
|
34086
|
+
return SecuritySystemMode.HomeArmed;
|
|
34102
34087
|
if (['arm_away', 'away', 'armed_away', 'away_armed'].includes(p))
|
|
34103
|
-
return
|
|
34088
|
+
return SecuritySystemMode.AwayArmed;
|
|
34104
34089
|
if (['arm_night', 'night', 'armed_night', 'sleep', 'arm_sleep', 'armed_sleep'].includes(p))
|
|
34105
|
-
return
|
|
34090
|
+
return SecuritySystemMode.NightArmed;
|
|
34106
34091
|
// transitori: non cambiano il mode
|
|
34107
34092
|
if (['entry_delay', 'exit_delay', 'pending', 'arming', 'disarming'].includes(p))
|
|
34108
34093
|
return undefined;
|
|
34109
34094
|
return undefined;
|
|
34110
34095
|
}
|
|
34111
|
-
class BaseMqttSensor extends
|
|
34096
|
+
class BaseMqttSensor extends ScryptedDeviceBase {
|
|
34112
34097
|
constructor(nativeId, cfg) {
|
|
34113
34098
|
super(nativeId);
|
|
34114
34099
|
this.cfg = cfg;
|
|
34115
|
-
// non impostare stati qui: l'annuncio device deve avvenire prima
|
|
34116
34100
|
}
|
|
34117
34101
|
/** Called by parent on each MQTT message */
|
|
34118
34102
|
handleMqtt(topic, payload) {
|
|
@@ -34141,9 +34125,7 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
|
|
|
34141
34125
|
this.batteryLevel = n;
|
|
34142
34126
|
}
|
|
34143
34127
|
else if (topic === this.cfg.topics.lowBattery && !this.cfg.topics.batteryLevel) {
|
|
34144
|
-
//
|
|
34145
|
-
// True -> 10% (warning)
|
|
34146
|
-
// False -> 100% (ok)
|
|
34128
|
+
// se abbiamo SOLO lowBattery (bool):
|
|
34147
34129
|
this.batteryLevel = truthy(np) ? 10 : 100;
|
|
34148
34130
|
}
|
|
34149
34131
|
// primary handled by subclasses
|
|
@@ -34151,37 +34133,28 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
|
|
|
34151
34133
|
}
|
|
34152
34134
|
}
|
|
34153
34135
|
class ContactMqttSensor extends BaseMqttSensor {
|
|
34154
|
-
|
|
34155
|
-
super(nativeId, cfg);
|
|
34156
|
-
}
|
|
34157
|
-
handlePrimary(topic, np, _raw) {
|
|
34136
|
+
handlePrimary(topic, np) {
|
|
34158
34137
|
if (topic === this.cfg.topics.contact) {
|
|
34159
34138
|
this.entryOpen = truthy(np);
|
|
34160
34139
|
}
|
|
34161
34140
|
}
|
|
34162
34141
|
}
|
|
34163
34142
|
class MotionMqttSensor extends BaseMqttSensor {
|
|
34164
|
-
|
|
34165
|
-
super(nativeId, cfg);
|
|
34166
|
-
}
|
|
34167
|
-
handlePrimary(topic, np, _raw) {
|
|
34143
|
+
handlePrimary(topic, np) {
|
|
34168
34144
|
if (topic === this.cfg.topics.motion) {
|
|
34169
34145
|
this.motionDetected = truthy(np);
|
|
34170
34146
|
}
|
|
34171
34147
|
}
|
|
34172
34148
|
}
|
|
34173
34149
|
class OccupancyMqttSensor extends BaseMqttSensor {
|
|
34174
|
-
|
|
34175
|
-
super(nativeId, cfg);
|
|
34176
|
-
}
|
|
34177
|
-
handlePrimary(topic, np, _raw) {
|
|
34150
|
+
handlePrimary(topic, np) {
|
|
34178
34151
|
if (topic === this.cfg.topics.occupancy) {
|
|
34179
34152
|
this.occupied = truthy(np);
|
|
34180
34153
|
}
|
|
34181
34154
|
}
|
|
34182
34155
|
}
|
|
34183
34156
|
/** ----------------- Main Plugin ----------------- */
|
|
34184
|
-
class ParadoxMqttSecuritySystem extends
|
|
34157
|
+
class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
|
|
34185
34158
|
constructor() {
|
|
34186
34159
|
super();
|
|
34187
34160
|
// sensor management
|
|
@@ -34190,26 +34163,26 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34190
34163
|
// (facoltativo) Imposta il device type in UI
|
|
34191
34164
|
setTimeout(() => {
|
|
34192
34165
|
try {
|
|
34193
|
-
systemManager.getDeviceById(this.id)?.setType?.(
|
|
34166
|
+
systemManager.getDeviceById(this.id)?.setType?.(ScryptedDeviceType.SecuritySystem);
|
|
34194
34167
|
}
|
|
34195
34168
|
catch { }
|
|
34196
34169
|
});
|
|
34197
34170
|
// Default state
|
|
34198
34171
|
this.securitySystemState = this.securitySystemState || {
|
|
34199
|
-
mode:
|
|
34172
|
+
mode: SecuritySystemMode.Disarmed,
|
|
34200
34173
|
supportedModes: [
|
|
34201
|
-
|
|
34202
|
-
|
|
34203
|
-
|
|
34204
|
-
|
|
34174
|
+
SecuritySystemMode.Disarmed,
|
|
34175
|
+
SecuritySystemMode.HomeArmed,
|
|
34176
|
+
SecuritySystemMode.AwayArmed,
|
|
34177
|
+
SecuritySystemMode.NightArmed,
|
|
34205
34178
|
],
|
|
34206
34179
|
};
|
|
34207
34180
|
this.online = this.online ?? false;
|
|
34208
34181
|
// Load sensors config and announce devices
|
|
34209
34182
|
this.loadSensorsFromStorage();
|
|
34210
|
-
this.discoverSensors().catch(e => this.console.error('discoverSensors error', e));
|
|
34183
|
+
this.discoverSensors().catch((e) => this.console.error('discoverSensors error', e));
|
|
34211
34184
|
// Connect on start
|
|
34212
|
-
this.connectMqtt().catch(e => this.console.error('MQTT connect error:', e));
|
|
34185
|
+
this.connectMqtt().catch((e) => this.console.error('MQTT connect error:', e));
|
|
34213
34186
|
// chiusura pulita del client MQTT ai reload/stop del plugin
|
|
34214
34187
|
try {
|
|
34215
34188
|
process.once('SIGTERM', () => { try {
|
|
@@ -34319,7 +34292,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34319
34292
|
this.saveSensorsToStorage();
|
|
34320
34293
|
try {
|
|
34321
34294
|
this.devices.delete(`sensor:${sid}`);
|
|
34322
|
-
deviceManager
|
|
34295
|
+
sdk?.deviceManager?.onDeviceRemoved?.(`sensor:${sid}`);
|
|
34323
34296
|
}
|
|
34324
34297
|
catch { }
|
|
34325
34298
|
// pulisci flag
|
|
@@ -34365,7 +34338,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34365
34338
|
this.devices.delete(nativeId);
|
|
34366
34339
|
}
|
|
34367
34340
|
try {
|
|
34368
|
-
deviceManager
|
|
34341
|
+
sdk?.deviceManager?.onDeviceRemoved?.(nativeId);
|
|
34369
34342
|
}
|
|
34370
34343
|
catch { }
|
|
34371
34344
|
}
|
|
@@ -34385,42 +34358,48 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34385
34358
|
this.sensorsCfg = [];
|
|
34386
34359
|
}
|
|
34387
34360
|
}
|
|
34388
|
-
/** ===== discoverSensors: annuncia PRIMA, istanzia DOPO ===== */
|
|
34361
|
+
/** ===== discoverSensors: annuncia PRIMA, istanzia DOPO (con retry se manager non pronto) ===== */
|
|
34389
34362
|
async discoverSensors() {
|
|
34390
|
-
|
|
34363
|
+
const dmAny = sdk?.deviceManager;
|
|
34364
|
+
if (!dmAny) {
|
|
34365
|
+
this.console.warn('deviceManager not ready yet, retrying in 1s…');
|
|
34366
|
+
setTimeout(() => this.discoverSensors().catch(e => this.console.error('discoverSensors retry error', e)), 1000);
|
|
34367
|
+
return;
|
|
34368
|
+
}
|
|
34369
|
+
// 1) Prepara i manifest
|
|
34391
34370
|
const manifests = this.sensorsCfg.map(cfg => {
|
|
34392
34371
|
const nativeId = `sensor:${cfg.id}`;
|
|
34393
34372
|
const t = cfg.topics || {};
|
|
34394
|
-
const interfaces = [
|
|
34395
|
-
// Tamper solo se c'è un topic tamper
|
|
34373
|
+
const interfaces = [ScryptedInterface.Online];
|
|
34396
34374
|
if (t.tamper)
|
|
34397
|
-
interfaces.push(
|
|
34398
|
-
// Interfaccia primaria
|
|
34375
|
+
interfaces.push(ScryptedInterface.TamperSensor);
|
|
34399
34376
|
if (cfg.kind === 'contact')
|
|
34400
|
-
interfaces.unshift(
|
|
34377
|
+
interfaces.unshift(ScryptedInterface.EntrySensor);
|
|
34401
34378
|
else if (cfg.kind === 'motion')
|
|
34402
|
-
interfaces.unshift(
|
|
34379
|
+
interfaces.unshift(ScryptedInterface.MotionSensor);
|
|
34403
34380
|
else
|
|
34404
|
-
interfaces.unshift(
|
|
34405
|
-
|
|
34406
|
-
|
|
34407
|
-
|
|
34408
|
-
}
|
|
34409
|
-
return { nativeId, name: cfg.name, type: sdk_1.ScryptedDeviceType.Sensor, interfaces };
|
|
34381
|
+
interfaces.unshift(ScryptedInterface.OccupancySensor);
|
|
34382
|
+
if (t.batteryLevel || t.lowBattery)
|
|
34383
|
+
interfaces.push(ScryptedInterface.Battery);
|
|
34384
|
+
return { nativeId, name: cfg.name, type: ScryptedDeviceType.Sensor, interfaces };
|
|
34410
34385
|
});
|
|
34411
34386
|
// 2) Annuncio
|
|
34412
|
-
const dmAny = deviceManager;
|
|
34413
34387
|
if (typeof dmAny.onDevicesChanged === 'function') {
|
|
34414
34388
|
dmAny.onDevicesChanged({ devices: manifests });
|
|
34415
34389
|
this.console.log('Annunciati (batch):', manifests.map(m => m.nativeId).join(', '));
|
|
34416
34390
|
}
|
|
34417
|
-
else {
|
|
34391
|
+
else if (typeof dmAny.onDeviceDiscovered === 'function') {
|
|
34418
34392
|
for (const m of manifests) {
|
|
34419
|
-
|
|
34393
|
+
dmAny.onDeviceDiscovered(m);
|
|
34420
34394
|
this.console.log('Annunciato:', m.nativeId);
|
|
34421
34395
|
}
|
|
34422
34396
|
}
|
|
34423
|
-
|
|
34397
|
+
else {
|
|
34398
|
+
this.console.warn('deviceManager has no discovery methods yet, retrying in 1s…');
|
|
34399
|
+
setTimeout(() => this.discoverSensors().catch(e => this.console.error('discoverSensors retry error', e)), 1000);
|
|
34400
|
+
return;
|
|
34401
|
+
}
|
|
34402
|
+
// 3) Istanzia/aggiorna
|
|
34424
34403
|
for (const cfg of this.sensorsCfg) {
|
|
34425
34404
|
const nativeId = `sensor:${cfg.id}`;
|
|
34426
34405
|
let dev = this.devices.get(nativeId);
|
|
@@ -34436,7 +34415,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34436
34415
|
else {
|
|
34437
34416
|
dev.cfg = cfg;
|
|
34438
34417
|
}
|
|
34439
|
-
// Default “OK” se abbiamo Battery ma nessun valore ancora ricevuto
|
|
34440
34418
|
const hasBattery = !!(cfg.topics.batteryLevel || cfg.topics.lowBattery);
|
|
34441
34419
|
if (hasBattery && dev.batteryLevel === undefined) {
|
|
34442
34420
|
dev.batteryLevel = 100;
|
|
@@ -34448,7 +34426,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34448
34426
|
if (!announced.has(nativeId)) {
|
|
34449
34427
|
try {
|
|
34450
34428
|
this.devices.delete(nativeId);
|
|
34451
|
-
deviceManager
|
|
34429
|
+
sdk?.deviceManager?.onDeviceRemoved?.(nativeId);
|
|
34452
34430
|
this.console.log('Rimosso:', nativeId);
|
|
34453
34431
|
}
|
|
34454
34432
|
catch { }
|
|
@@ -34551,14 +34529,14 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34551
34529
|
if (topic === tCurrent) {
|
|
34552
34530
|
const mode = payloadToMode(payload);
|
|
34553
34531
|
const isAlarm = ['alarm', 'triggered'].includes(np);
|
|
34554
|
-
const current = this.securitySystemState || { mode:
|
|
34532
|
+
const current = this.securitySystemState || { mode: SecuritySystemMode.Disarmed };
|
|
34555
34533
|
const newState = {
|
|
34556
34534
|
mode: mode ?? current.mode,
|
|
34557
34535
|
supportedModes: current.supportedModes ?? [
|
|
34558
|
-
|
|
34559
|
-
|
|
34560
|
-
|
|
34561
|
-
|
|
34536
|
+
SecuritySystemMode.Disarmed,
|
|
34537
|
+
SecuritySystemMode.HomeArmed,
|
|
34538
|
+
SecuritySystemMode.AwayArmed,
|
|
34539
|
+
SecuritySystemMode.NightArmed,
|
|
34562
34540
|
],
|
|
34563
34541
|
triggered: isAlarm || undefined,
|
|
34564
34542
|
};
|
|
@@ -34602,17 +34580,17 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
|
|
|
34602
34580
|
this.publishSetTarget(payload);
|
|
34603
34581
|
}
|
|
34604
34582
|
async disarmSecuritySystem() {
|
|
34605
|
-
const payload = this.getOutgoing(
|
|
34583
|
+
const payload = this.getOutgoing(SecuritySystemMode.Disarmed);
|
|
34606
34584
|
this.console.log('disarmSecuritySystem ->', payload);
|
|
34607
|
-
this.pendingTarget =
|
|
34585
|
+
this.pendingTarget = SecuritySystemMode.Disarmed;
|
|
34608
34586
|
this.publishSetTarget(payload);
|
|
34609
34587
|
}
|
|
34610
34588
|
getOutgoing(mode) {
|
|
34611
34589
|
const map = {
|
|
34612
|
-
[
|
|
34613
|
-
[
|
|
34614
|
-
[
|
|
34615
|
-
[
|
|
34590
|
+
[SecuritySystemMode.Disarmed]: this.storage.getItem('payloadDisarm') || DEFAULT_OUTGOING[SecuritySystemMode.Disarmed],
|
|
34591
|
+
[SecuritySystemMode.HomeArmed]: this.storage.getItem('payloadHome') || DEFAULT_OUTGOING[SecuritySystemMode.HomeArmed],
|
|
34592
|
+
[SecuritySystemMode.AwayArmed]: this.storage.getItem('payloadAway') || DEFAULT_OUTGOING[SecuritySystemMode.AwayArmed],
|
|
34593
|
+
[SecuritySystemMode.NightArmed]: this.storage.getItem('payloadNight') || DEFAULT_OUTGOING[SecuritySystemMode.NightArmed],
|
|
34616
34594
|
};
|
|
34617
34595
|
return map[mode];
|
|
34618
34596
|
}
|
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED