@rfranzoi/scrypted-mqtt-securitysystem 1.0.19 → 1.0.20

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.
@@ -34083,9 +34083,6 @@ function normalize(s) {
34083
34083
  function clamp(n, min, max) {
34084
34084
  return Math.max(min, Math.min(max, n));
34085
34085
  }
34086
- function delay(ms) {
34087
- return new Promise(res => setTimeout(res, ms));
34088
- }
34089
34086
  /** SecuritySystem outgoing defaults (PAI-like) */
34090
34087
  const DEFAULT_OUTGOING = {
34091
34088
  [sdk_1.SecuritySystemMode.Disarmed]: 'disarm',
@@ -34115,7 +34112,7 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34115
34112
  constructor(nativeId, cfg) {
34116
34113
  super(nativeId);
34117
34114
  this.cfg = cfg;
34118
- this.online = this.online ?? true;
34115
+ // ⚠️ Non toccare stati nel costruttore (discovery non ancora completata)
34119
34116
  }
34120
34117
  /** Called by parent on each MQTT message */
34121
34118
  handleMqtt(topic, payload) {
@@ -34208,7 +34205,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34208
34205
  this.online = this.online ?? false;
34209
34206
  // Load sensors config and announce devices
34210
34207
  this.loadSensorsFromStorage();
34211
- this.discoverSensors();
34208
+ this.discoverSensors().catch(e => this.console.error('discoverSensors error', e));
34212
34209
  // Connect on start
34213
34210
  this.connectMqtt().catch(e => this.console.error('MQTT connect error:', e));
34214
34211
  // chiusura pulita del client MQTT ai reload/stop del plugin
@@ -34276,7 +34273,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34276
34273
  async getDevice(nativeId) {
34277
34274
  return this.devices.get(nativeId);
34278
34275
  }
34279
- async releaseDevice(id, nativeId) {
34276
+ async releaseDevice(_id, nativeId) {
34280
34277
  try {
34281
34278
  const dev = this.devices.get(nativeId);
34282
34279
  if (dev) {
@@ -34303,75 +34300,64 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34303
34300
  this.sensorsCfg = [];
34304
34301
  }
34305
34302
  }
34306
- /** ===== discoverSensors con interfacce dinamiche (Battery/Tamper opzionali) ===== */
34303
+ /** ===== discoverSensors: annuncia PRIMA, istanzia DOPO ===== */
34307
34304
  async discoverSensors() {
34305
+ // 1) Prepara i manifest (niente istanze qui)
34308
34306
  const manifests = this.sensorsCfg.map(cfg => {
34309
34307
  const nativeId = `sensor:${cfg.id}`;
34308
+ // interfacce dinamiche
34310
34309
  const t = cfg.topics || {};
34311
- // Interfacce di base: Online sempre
34312
- const interfaces = [sdk_1.ScryptedInterface.Online];
34313
- // Aggiungi primaria in base al kind
34314
- switch (cfg.kind) {
34315
- case 'contact':
34316
- interfaces.unshift(sdk_1.ScryptedInterface.EntrySensor);
34317
- break;
34318
- case 'motion':
34319
- interfaces.unshift(sdk_1.ScryptedInterface.MotionSensor);
34320
- break;
34321
- case 'occupancy':
34322
- interfaces.unshift(sdk_1.ScryptedInterface.OccupancySensor);
34323
- break;
34324
- }
34325
- // Tamper solo se presente il topic
34326
- if (t.tamper)
34327
- interfaces.push(sdk_1.ScryptedInterface.TamperSensor);
34328
- // Battery solo se presente batteryLevel o lowBattery
34329
- if (t.batteryLevel || t.lowBattery)
34310
+ const interfaces = [
34311
+ sdk_1.ScryptedInterface.Online,
34312
+ sdk_1.ScryptedInterface.TamperSensor,
34313
+ ];
34314
+ if (cfg.kind === 'contact')
34315
+ interfaces.unshift(sdk_1.ScryptedInterface.EntrySensor);
34316
+ else if (cfg.kind === 'motion')
34317
+ interfaces.unshift(sdk_1.ScryptedInterface.MotionSensor);
34318
+ else
34319
+ interfaces.unshift(sdk_1.ScryptedInterface.OccupancySensor);
34320
+ // aggiungi Battery solo se previsto
34321
+ if (t.batteryLevel || t.lowBattery) {
34330
34322
  interfaces.push(sdk_1.ScryptedInterface.Battery);
34331
- // Tipo generico "Sensor": le capacità sono date dalle interfacce
34332
- const type = sdk_1.ScryptedDeviceType.Sensor;
34333
- // create/update instance
34334
- let dev = this.devices.get(nativeId);
34335
- if (!dev) {
34336
- if (cfg.kind === 'contact')
34337
- dev = new ContactMqttSensor(nativeId, cfg);
34338
- else if (cfg.kind === 'motion')
34339
- dev = new MotionMqttSensor(nativeId, cfg);
34340
- else
34341
- dev = new OccupancyMqttSensor(nativeId, cfg);
34342
- this.devices.set(nativeId, dev);
34343
- }
34344
- else {
34345
- dev.cfg = cfg;
34346
- // se non c'è più batteria nei topic, pulisci eventuale valore residuo
34347
- if (!(t.batteryLevel || t.lowBattery)) {
34348
- try {
34349
- dev.batteryLevel = undefined;
34350
- }
34351
- catch { }
34352
- }
34353
34323
  }
34354
34324
  return {
34355
34325
  nativeId,
34356
34326
  name: cfg.name,
34357
- type,
34327
+ type: sdk_1.ScryptedDeviceType.Sensor,
34358
34328
  interfaces,
34359
34329
  };
34360
34330
  });
34361
- // Annuncio in batch se disponibile, altrimenti uno per volta con un piccolo delay
34362
- const dm = deviceManager;
34363
- if (typeof dm.onDevicesChanged === 'function') {
34364
- dm.onDevicesChanged({ devices: manifests });
34331
+ // 2) Annuncia i device
34332
+ const dmAny = deviceManager;
34333
+ if (typeof dmAny.onDevicesChanged === 'function') {
34334
+ dmAny.onDevicesChanged({ devices: manifests });
34365
34335
  this.console.log('Annunciati (batch):', manifests.map(m => m.nativeId).join(', '));
34366
34336
  }
34367
34337
  else {
34368
34338
  for (const m of manifests) {
34369
34339
  deviceManager.onDeviceDiscovered(m);
34370
34340
  this.console.log('Annunciato:', m.nativeId);
34371
- await delay(50);
34372
34341
  }
34373
34342
  }
34374
- // Rimuovi eventuali sensori non più presenti
34343
+ // 3) Istanzia/aggiorna le classi DOPO l’annuncio
34344
+ for (const cfg of this.sensorsCfg) {
34345
+ const nativeId = `sensor:${cfg.id}`;
34346
+ let dev = this.devices.get(nativeId);
34347
+ if (!dev) {
34348
+ if (cfg.kind === 'contact')
34349
+ dev = new ContactMqttSensor(nativeId, cfg);
34350
+ else if (cfg.kind === 'motion')
34351
+ dev = new MotionMqttSensor(nativeId, cfg);
34352
+ else
34353
+ dev = new OccupancyMqttSensor(nativeId, cfg);
34354
+ this.devices.set(nativeId, dev);
34355
+ }
34356
+ else {
34357
+ dev.cfg = cfg;
34358
+ }
34359
+ }
34360
+ // 4) Rimuovi quelli spariti
34375
34361
  const announced = new Set(manifests.map(m => m.nativeId));
34376
34362
  for (const [nativeId] of this.devices) {
34377
34363
  if (!announced.has(nativeId)) {
@@ -34415,7 +34401,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34415
34401
  }
34416
34402
  // sensors
34417
34403
  for (const s of this.sensorsCfg) {
34418
- const t = s.topics;
34404
+ const t = s.topics || {};
34419
34405
  [t.contact, t.motion, t.occupancy, t.batteryLevel, t.lowBattery, t.tamper, t.online]
34420
34406
  .filter(Boolean)
34421
34407
  .forEach(x => subs.add(String(x)));
package/dist/plugin.zip CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rfranzoi/scrypted-mqtt-securitysystem",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Scrypted plugin: Paradox Security System via MQTT (PAI/PAI-MQTT style).",
5
5
  "license": "MIT",
6
6
  "main": "dist/main.nodejs.js",