@rfranzoi/scrypted-mqtt-securitysystem 1.0.92 → 1.0.93

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.
@@ -34241,9 +34241,10 @@ function payloadToModeLoose(payload) {
34241
34241
  return undefined;
34242
34242
  }
34243
34243
  class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34244
- constructor(nativeId, cfg) {
34244
+ constructor(nativeId, cfg, publishBypass) {
34245
34245
  super(nativeId);
34246
34246
  this.cfg = cfg;
34247
+ this.publishBypass = publishBypass;
34247
34248
  }
34248
34249
  /** setter centralizzato + evento + (log opzionale) */
34249
34250
  setAndEmit(prop, val, iface, logContext) {
@@ -34299,7 +34300,17 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34299
34300
  });
34300
34301
  return;
34301
34302
  }
34302
- // 4) LOW BATTERY (bool)
34303
+ // 4) BYPASS STATE
34304
+ if (topic === this.cfg.bypass?.state) {
34305
+ if (truthy(np)) {
34306
+ this.setAndEmit('on', true, sdk_1.ScryptedInterface.OnOff, { topic, raw, propLabel: 'bypass' });
34307
+ }
34308
+ else if (falsy(np)) {
34309
+ this.setAndEmit('on', false, sdk_1.ScryptedInterface.OnOff, { topic, raw, propLabel: 'bypass' });
34310
+ }
34311
+ return;
34312
+ }
34313
+ // 5) LOW BATTERY (bool)
34303
34314
  if (topic === topics.lowBattery) {
34304
34315
  const isLow = np === 'true' ||
34305
34316
  np === '1' ||
@@ -34322,7 +34333,7 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34322
34333
  }
34323
34334
  return;
34324
34335
  }
34325
- // 5) BATTERY LEVEL (0..100)
34336
+ // 6) BATTERY LEVEL (0..100)
34326
34337
  if (topic === topics.batteryLevel) {
34327
34338
  const n = Number(raw);
34328
34339
  if (isFinite(n)) {
@@ -34342,6 +34353,34 @@ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34342
34353
  return;
34343
34354
  }
34344
34355
  }
34356
+ async turnOn() {
34357
+ const bypass = this.cfg.bypass;
34358
+ if (!bypass?.control) {
34359
+ this.console?.warn?.('Bypass control topic non configurato.');
34360
+ return;
34361
+ }
34362
+ const payload = (bypass.payloadOn || 'bypass').trim() || 'bypass';
34363
+ if (this.publishBypass(this.cfg, payload))
34364
+ this.setAndEmit('on', true, sdk_1.ScryptedInterface.OnOff, { propLabel: 'bypass' });
34365
+ }
34366
+ async turnOff() {
34367
+ const bypass = this.cfg.bypass;
34368
+ if (!bypass?.control) {
34369
+ this.console?.warn?.('Bypass control topic non configurato.');
34370
+ return;
34371
+ }
34372
+ const payload = (bypass.payloadOff || 'clear_bypass').trim() || 'clear_bypass';
34373
+ if (this.publishBypass(this.cfg, payload))
34374
+ this.setAndEmit('on', false, sdk_1.ScryptedInterface.OnOff, { propLabel: 'bypass' });
34375
+ }
34376
+ async setPowerState(on) {
34377
+ if (on)
34378
+ return this.turnOn();
34379
+ return this.turnOff();
34380
+ }
34381
+ async setOn(on) {
34382
+ return this.setPowerState(on);
34383
+ }
34345
34384
  }
34346
34385
  class ContactMqttSensor extends BaseMqttSensor {
34347
34386
  handlePrimary(topic, np, raw) {
@@ -34367,75 +34406,12 @@ class OccupancyMqttSensor extends BaseMqttSensor {
34367
34406
  }
34368
34407
  }
34369
34408
  }
34370
- class BypassMqttSwitch extends sdk_1.ScryptedDeviceBase {
34371
- constructor(nativeId, cfg, parent) {
34372
- super(nativeId);
34373
- this.cfg = cfg;
34374
- this.parent = parent;
34375
- }
34376
- updateConfig(cfg) {
34377
- this.cfg = cfg;
34378
- }
34379
- setOnState(val, logContext) {
34380
- if (this.on === val)
34381
- return;
34382
- this.on = val;
34383
- try {
34384
- this.onDeviceEvent(sdk_1.ScryptedInterface.OnOff, val);
34385
- }
34386
- catch (e) {
34387
- this.console?.warn?.('onDeviceEvent error', e);
34388
- }
34389
- if (RUNTIME.logSensors) {
34390
- const source = logContext?.source ? ` ${logContext.source}` : '';
34391
- const extra = logContext?.topic ? ` (${logContext.topic}="${logContext.raw ?? ''}")` : '';
34392
- this.console?.log?.(`[Bypass] ${this.cfg.zoneName} [${this.cfg.id}] on -> ${val}${source}${extra}`);
34393
- }
34394
- }
34395
- handleMqtt(topic, payload) {
34396
- if (topic !== this.cfg.topics.state)
34397
- return;
34398
- const raw = payload?.toString() ?? '';
34399
- const np = normalize(raw);
34400
- if (truthy(np))
34401
- this.setOnState(true, { topic, raw, source: 'state' });
34402
- else if (falsy(np))
34403
- this.setOnState(false, { topic, raw, source: 'state' });
34404
- }
34405
- async turnOn() {
34406
- if (RUNTIME.logSensors) {
34407
- const topic = this.cfg.topics?.control || '';
34408
- this.console?.log?.(`[Bypass] cmd ON ${this.cfg.zoneName} [${this.cfg.id}] -> ${topic}`);
34409
- }
34410
- const payload = (this.cfg.payloadOn || 'bypass').trim() || 'bypass';
34411
- if (this.parent.publishBypass(this.cfg, payload))
34412
- this.setOnState(true, { source: 'local' });
34413
- }
34414
- async turnOff() {
34415
- if (RUNTIME.logSensors) {
34416
- const topic = this.cfg.topics?.control || '';
34417
- this.console?.log?.(`[Bypass] cmd OFF ${this.cfg.zoneName} [${this.cfg.id}] -> ${topic}`);
34418
- }
34419
- const payload = (this.cfg.payloadOff || 'clear_bypass').trim() || 'clear_bypass';
34420
- if (this.parent.publishBypass(this.cfg, payload))
34421
- this.setOnState(false, { source: 'local' });
34422
- }
34423
- async setPowerState(on) {
34424
- if (on)
34425
- return this.turnOn();
34426
- return this.turnOff();
34427
- }
34428
- async setOn(on) {
34429
- return this.setPowerState(on);
34430
- }
34431
- }
34432
34409
  /** ----------------- Main Plugin ----------------- */
34433
34410
  class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34434
34411
  constructor() {
34435
34412
  super();
34436
34413
  // sensor management
34437
34414
  this.sensorsCfg = [];
34438
- this.bypassCfg = [];
34439
34415
  this.devices = new Map();
34440
34416
  // carica flag runtime
34441
34417
  updateRuntimeFromStorage((k) => this.storage.getItem(k) || '');
@@ -34459,7 +34435,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34459
34435
  this.online = this.online ?? false;
34460
34436
  // Load configs and announce devices
34461
34437
  this.loadSensorsFromStorage();
34462
- this.loadBypassFromStorage();
34463
34438
  this.discoverDevices().catch(e => this.console.error('discoverDevices error', e));
34464
34439
  // Connect on start
34465
34440
  this.connectMqtt().catch(e => this.console.error('MQTT connect error:', e));
@@ -34540,14 +34515,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34540
34515
  this.console.error('saveSensorsToStorage error', e);
34541
34516
  }
34542
34517
  }
34543
- saveBypassToStorage() {
34544
- try {
34545
- this.storage.setItem('bypassJson', JSON.stringify(this.bypassCfg));
34546
- }
34547
- catch (e) {
34548
- this.console.error('saveBypassToStorage error', e);
34549
- }
34550
- }
34551
34518
  /** ---- Settings UI ---- */
34552
34519
  async getSettings() {
34553
34520
  const out = [
@@ -34582,8 +34549,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34582
34549
  ];
34583
34550
  // ---- UI Add Sensor ----
34584
34551
  out.push({ group: 'Add Sensor', key: 'new.id', title: 'New Sensor ID', placeholder: 'porta-ingresso', value: this.storage.getItem('new.id') || '' }, { group: 'Add Sensor', key: 'new.name', title: 'Name', placeholder: 'Porta Ingresso', value: this.storage.getItem('new.name') || '' }, { group: 'Add Sensor', key: 'new.kind', title: 'Type', value: this.storage.getItem('new.kind') || 'contact', choices: ['contact', 'motion', 'occupancy'] }, { group: 'Add Sensor', key: 'new.create', title: 'Create sensor', type: 'boolean', description: 'Fill the fields above and toggle this on to create the sensor. After creation, restart this plugin to see the accessory listed below. To show it in HomeKit, restart the HomeKit plugin as well.' });
34585
- // ---- UI Add Bypass Switch ----
34586
- out.push({ group: 'Add Bypass Switch', key: 'bypass.new.id', title: 'New Bypass ID', placeholder: 'zona-1', value: this.storage.getItem('bypass.new.id') || '' }, { group: 'Add Bypass Switch', key: 'bypass.new.zoneName', title: 'Zone Name', placeholder: 'Zona 1', value: this.storage.getItem('bypass.new.zoneName') || '' }, { group: 'Add Bypass Switch', key: 'bypass.new.topic.control', title: 'Control Topic', placeholder: 'paradox/control/zones/Zona_1', value: this.storage.getItem('bypass.new.topic.control') || '' }, { group: 'Add Bypass Switch', key: 'bypass.new.topic.state', title: 'State Topic', placeholder: 'paradox/states/zones/Zona_1/bypassed', value: this.storage.getItem('bypass.new.topic.state') || '' }, { group: 'Add Bypass Switch', key: 'bypass.new.payloadOn', title: 'Payload for ON', placeholder: 'bypass', value: this.storage.getItem('bypass.new.payloadOn') || 'bypass' }, { group: 'Add Bypass Switch', key: 'bypass.new.payloadOff', title: 'Payload for OFF', placeholder: 'clear_bypass', value: this.storage.getItem('bypass.new.payloadOff') || 'clear_bypass' }, { group: 'Add Bypass Switch', key: 'bypass.new.create', title: 'Create bypass switch', type: 'boolean', description: 'Fill the fields above and toggle this on to create the bypass switch. After creation, restart this plugin to see the accessory listed below.' });
34587
34552
  // ---- UI per sensori esistenti ----
34588
34553
  for (const cfg of this.sensorsCfg) {
34589
34554
  const gid = `Sensor: ${cfg.name} [${cfg.id}]`;
@@ -34594,12 +34559,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34594
34559
  out.push({ group: gid, key: `sensor.${cfg.id}.topic.motion`, title: 'Motion Detected Topic', value: cfg.topics.motion || '', placeholder: 'paradox/states/zones/XYZ/open' });
34595
34560
  else
34596
34561
  out.push({ group: gid, key: `sensor.${cfg.id}.topic.occupancy`, title: 'Occupancy Detected Topic', value: cfg.topics.occupancy || '', placeholder: 'paradox/states/zones/XYZ/open' });
34597
- out.push({ group: gid, key: `sensor.${cfg.id}.topic.batteryLevel`, title: 'Battery Level Topic (0..100)', value: cfg.topics.batteryLevel || '' }, { group: gid, key: `sensor.${cfg.id}.topic.lowBattery`, title: 'Low Battery Topic (bool)', value: cfg.topics.lowBattery || '' }, { group: gid, key: `sensor.${cfg.id}.topic.tamper`, title: 'Tamper Topic', value: cfg.topics.tamper || '' }, { group: gid, key: `sensor.${cfg.id}.topic.online`, title: 'Online Topic', value: cfg.topics.online || '' }, { group: gid, key: `sensor.${cfg.id}.remove`, title: 'Remove sensor', type: 'boolean' });
34598
- }
34599
- // ---- UI per bypass esistenti ----
34600
- for (const cfg of this.bypassCfg) {
34601
- const gid = `Bypass: ${cfg.zoneName} [${cfg.id}]`;
34602
- out.push({ group: gid, key: `bypass.${cfg.id}.zoneName`, title: 'Zone Name', value: cfg.zoneName }, { group: gid, key: `bypass.${cfg.id}.topic.control`, title: 'Control Topic', value: cfg.topics.control || '', placeholder: 'paradox/control/zones/Zona_1' }, { group: gid, key: `bypass.${cfg.id}.topic.state`, title: 'State Topic', value: cfg.topics.state || '', placeholder: 'paradox/states/zones/Zona_1/bypassed' }, { group: gid, key: `bypass.${cfg.id}.payloadOn`, title: 'Payload for ON', value: cfg.payloadOn || 'bypass' }, { group: gid, key: `bypass.${cfg.id}.payloadOff`, title: 'Payload for OFF', value: cfg.payloadOff || 'clear_bypass' }, { group: gid, key: `bypass.${cfg.id}.remove`, title: 'Remove bypass switch', type: 'boolean' });
34562
+ out.push({ group: gid, key: `sensor.${cfg.id}.topic.batteryLevel`, title: 'Battery Level Topic (0..100)', value: cfg.topics.batteryLevel || '' }, { group: gid, key: `sensor.${cfg.id}.topic.lowBattery`, title: 'Low Battery Topic (bool)', value: cfg.topics.lowBattery || '' }, { group: gid, key: `sensor.${cfg.id}.topic.tamper`, title: 'Tamper Topic', value: cfg.topics.tamper || '' }, { group: gid, key: `sensor.${cfg.id}.topic.online`, title: 'Online Topic', value: cfg.topics.online || '' }, { group: gid, key: `sensor.${cfg.id}.bypass.control`, title: 'Bypass Control Topic', value: cfg.bypass?.control || '', placeholder: 'paradox/control/zones/Zona_1' }, { group: gid, key: `sensor.${cfg.id}.bypass.state`, title: 'Bypass State Topic', value: cfg.bypass?.state || '', placeholder: 'paradox/states/zones/Zona_1/bypassed' }, { group: gid, key: `sensor.${cfg.id}.bypass.payloadOn`, title: 'Bypass Payload ON', value: cfg.bypass?.payloadOn || 'bypass' }, { group: gid, key: `sensor.${cfg.id}.bypass.payloadOff`, title: 'Bypass Payload OFF', value: cfg.bypass?.payloadOff || 'clear_bypass' }, { group: gid, key: `sensor.${cfg.id}.remove`, title: 'Remove sensor', type: 'boolean' });
34603
34563
  }
34604
34564
  return out;
34605
34565
  }
@@ -34632,44 +34592,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34632
34592
  await this.connectMqtt(true);
34633
34593
  return;
34634
34594
  }
34635
- // --- Add Bypass Switch workflow ---
34636
- if (key === 'bypass.new.create' && String(value) === 'true') {
34637
- const id = (this.storage.getItem('bypass.new.id') || '').trim();
34638
- const zoneName = (this.storage.getItem('bypass.new.zoneName') || '').trim() || id;
34639
- const control = (this.storage.getItem('bypass.new.topic.control') || '').trim();
34640
- const state = (this.storage.getItem('bypass.new.topic.state') || '').trim();
34641
- const payloadOn = (this.storage.getItem('bypass.new.payloadOn') || 'bypass').trim() || 'bypass';
34642
- const payloadOff = (this.storage.getItem('bypass.new.payloadOff') || 'clear_bypass').trim() || 'clear_bypass';
34643
- if (!id) {
34644
- this.console.warn('Create bypass: id mancante');
34645
- return;
34646
- }
34647
- if (this.bypassCfg.find(b => b.id === id)) {
34648
- this.console.warn('Create bypass: id già esistente');
34649
- return;
34650
- }
34651
- this.bypassCfg.push({
34652
- id,
34653
- zoneName,
34654
- topics: { control, state },
34655
- payloadOn,
34656
- payloadOff,
34657
- });
34658
- this.saveBypassToStorage();
34659
- // pulizia campi "bypass.new.*"
34660
- this.storage.removeItem('bypass.new.id');
34661
- this.storage.removeItem('bypass.new.zoneName');
34662
- this.storage.removeItem('bypass.new.topic.control');
34663
- this.storage.removeItem('bypass.new.topic.state');
34664
- this.storage.removeItem('bypass.new.payloadOn');
34665
- this.storage.removeItem('bypass.new.payloadOff');
34666
- this.storage.removeItem('bypass.new.create');
34667
- await this.discoverDevices();
34668
- await this.connectMqtt(true);
34669
- return;
34670
- }
34671
- if (key.startsWith('bypass.new.'))
34672
- return;
34673
34595
  // --- Edit/Remove sensore esistente ---
34674
34596
  const m = key.match(/^sensor\.([^\.]+)\.(.+)$/);
34675
34597
  if (m) {
@@ -34703,53 +34625,19 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34703
34625
  const tk = prop.substring('topic.'.length);
34704
34626
  cfg.topics[tk] = String(value).trim();
34705
34627
  }
34706
- this.saveSensorsToStorage();
34707
- await this.discoverDevices();
34708
- await this.connectMqtt(true);
34709
- return;
34710
- }
34711
- // --- Edit/Remove bypass esistente ---
34712
- const mb = key.match(/^bypass\.([^\.]+)\.(.+)$/);
34713
- if (mb) {
34714
- const bid = mb[1];
34715
- const prop = mb[2];
34716
- const cfg = this.bypassCfg.find(b => b.id === bid);
34717
- if (!cfg) {
34718
- this.console.warn('putSetting: bypass non trovato', bid);
34719
- return;
34720
- }
34721
- if (prop === 'remove' && String(value) === 'true') {
34722
- this.bypassCfg = this.bypassCfg.filter(b => b.id !== bid);
34723
- this.saveBypassToStorage();
34724
- try {
34725
- this.devices.delete(`bypass:${bid}`);
34726
- deviceManager.onDeviceRemoved?.(`bypass:${bid}`);
34727
- }
34728
- catch { }
34729
- this.storage.removeItem(key);
34730
- await this.discoverDevices();
34731
- await this.connectMqtt(true);
34732
- return;
34733
- }
34734
- if (prop === 'zoneName')
34735
- cfg.zoneName = String(value);
34736
- else if (prop === 'payloadOn')
34737
- cfg.payloadOn = String(value).trim();
34738
- else if (prop === 'payloadOff')
34739
- cfg.payloadOff = String(value).trim();
34740
- else if (prop.startsWith('topic.')) {
34741
- const tk = prop.substring('topic.'.length);
34742
- cfg.topics[tk] = String(value).trim();
34628
+ else if (prop.startsWith('bypass.')) {
34629
+ const bk = prop.substring('bypass.'.length);
34630
+ cfg.bypass = cfg.bypass || {};
34631
+ cfg.bypass[bk] = String(value).trim();
34743
34632
  }
34744
- this.saveBypassToStorage();
34633
+ this.saveSensorsToStorage();
34745
34634
  await this.discoverDevices();
34746
34635
  await this.connectMqtt(true);
34747
34636
  return;
34748
34637
  }
34749
34638
  // --- Altro (MQTT / Alarm settings / parsing / payloads / logging) ---
34750
- if (key === 'sensorsJson' || key === 'bypassJson') {
34639
+ if (key === 'sensorsJson') {
34751
34640
  this.loadSensorsFromStorage();
34752
- this.loadBypassFromStorage();
34753
34641
  await this.discoverDevices();
34754
34642
  await this.connectMqtt(true);
34755
34643
  }
@@ -34771,11 +34659,11 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34771
34659
  return undefined;
34772
34660
  let dev;
34773
34661
  if (cfg.kind === 'contact')
34774
- dev = new ContactMqttSensor(nativeId, cfg);
34662
+ dev = new ContactMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34775
34663
  else if (cfg.kind === 'motion')
34776
- dev = new MotionMqttSensor(nativeId, cfg);
34664
+ dev = new MotionMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34777
34665
  else
34778
- dev = new OccupancyMqttSensor(nativeId, cfg);
34666
+ dev = new OccupancyMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34779
34667
  this.devices.set(nativeId, dev);
34780
34668
  const hasBattery = !!(cfg.topics.batteryLevel && cfg.topics.batteryLevel.trim())
34781
34669
  || !!(cfg.topics.lowBattery && cfg.topics.lowBattery.trim());
@@ -34788,17 +34676,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34788
34676
  }
34789
34677
  return dev;
34790
34678
  }
34791
- if (nativeId.startsWith('bypass:')) {
34792
- const bid = nativeId.substring('bypass:'.length);
34793
- const cfg = this.bypassCfg.find(b => b.id === bid);
34794
- if (!cfg)
34795
- return undefined;
34796
- const dev = new BypassMqttSwitch(nativeId, cfg, this);
34797
- if (dev.on === undefined)
34798
- dev.on = false;
34799
- this.devices.set(nativeId, dev);
34800
- return dev;
34801
- }
34802
34679
  return undefined;
34803
34680
  }
34804
34681
  async releaseDevice(_id, nativeId) {
@@ -34820,31 +34697,22 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34820
34697
  const raw = this.storage.getItem('sensorsJson') || '[]';
34821
34698
  const parsed = JSON.parse(raw);
34822
34699
  // sanitize
34823
- this.sensorsCfg = (parsed || []).filter(x => x && x.id && x.name && x.kind && x.topics);
34824
- }
34825
- catch (e) {
34826
- this.console.error('Invalid sensorsJson:', e);
34827
- this.sensorsCfg = [];
34828
- }
34829
- }
34830
- loadBypassFromStorage() {
34831
- try {
34832
- const raw = this.storage.getItem('bypassJson') || '[]';
34833
- const parsed = JSON.parse(raw);
34834
- this.bypassCfg = (parsed || []).filter(x => x && x.id && x.zoneName && x.topics).map(x => ({
34700
+ this.sensorsCfg = (parsed || []).filter(x => x && x.id && x.name && x.kind && x.topics).map(x => ({
34835
34701
  id: String(x.id),
34836
- zoneName: String(x.zoneName),
34837
- topics: {
34838
- control: x.topics?.control || '',
34839
- state: x.topics?.state || '',
34702
+ name: String(x.name),
34703
+ kind: x.kind,
34704
+ topics: x.topics || {},
34705
+ bypass: {
34706
+ control: x.bypass?.control || '',
34707
+ state: x.bypass?.state || '',
34708
+ payloadOn: x.bypass?.payloadOn || 'bypass',
34709
+ payloadOff: x.bypass?.payloadOff || 'clear_bypass',
34840
34710
  },
34841
- payloadOn: String(x.payloadOn || 'bypass'),
34842
- payloadOff: String(x.payloadOff || 'clear_bypass'),
34843
34711
  }));
34844
34712
  }
34845
34713
  catch (e) {
34846
- this.console.error('Invalid bypassJson:', e);
34847
- this.bypassCfg = [];
34714
+ this.console.error('Invalid sensorsJson:', e);
34715
+ this.sensorsCfg = [];
34848
34716
  }
34849
34717
  }
34850
34718
  /** ===== discoverDevices: annuncia PRIMA, istanzia DOPO ===== */
@@ -34866,15 +34734,11 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34866
34734
  // Battery solo se definita davvero
34867
34735
  if ((t.batteryLevel && t.batteryLevel.trim()) || (t.lowBattery && t.lowBattery.trim()))
34868
34736
  interfaces.push(sdk_1.ScryptedInterface.Battery);
34737
+ const hasBypass = !!(cfg.bypass?.control?.trim() || cfg.bypass?.state?.trim());
34738
+ if (hasBypass)
34739
+ interfaces.push(sdk_1.ScryptedInterface.OnOff);
34869
34740
  manifests.push({ nativeId, name: cfg.name, type: sdk_1.ScryptedDeviceType.Sensor, interfaces });
34870
34741
  }
34871
- for (const cfg of this.bypassCfg) {
34872
- const nativeId = `bypass:${cfg.id}`;
34873
- const zoneName = (cfg.zoneName || '').trim() || cfg.id;
34874
- const name = `${zoneName} Bypass`;
34875
- const interfaces = [sdk_1.ScryptedInterface.OnOff];
34876
- manifests.push({ nativeId, name, type: sdk_1.ScryptedDeviceType.Switch, interfaces });
34877
- }
34878
34742
  // 2) annuncio
34879
34743
  const dmAny = deviceManager;
34880
34744
  if (typeof dmAny.onDevicesChanged === 'function') {
@@ -34896,11 +34760,11 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34896
34760
  let dev = this.devices.get(nativeId);
34897
34761
  if (!dev) {
34898
34762
  if (cfg.kind === 'contact')
34899
- dev = new ContactMqttSensor(nativeId, cfg);
34763
+ dev = new ContactMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34900
34764
  else if (cfg.kind === 'motion')
34901
- dev = new MotionMqttSensor(nativeId, cfg);
34765
+ dev = new MotionMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34902
34766
  else
34903
- dev = new OccupancyMqttSensor(nativeId, cfg);
34767
+ dev = new OccupancyMqttSensor(nativeId, cfg, this.publishSensorBypass.bind(this));
34904
34768
  this.devices.set(nativeId, dev);
34905
34769
  }
34906
34770
  else {
@@ -34917,17 +34781,6 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34917
34781
  catch { }
34918
34782
  }
34919
34783
  }
34920
- for (const cfg of this.bypassCfg) {
34921
- const nativeId = `bypass:${cfg.id}`;
34922
- let dev = this.devices.get(nativeId);
34923
- if (!dev) {
34924
- dev = new BypassMqttSwitch(nativeId, cfg, this);
34925
- this.devices.set(nativeId, dev);
34926
- }
34927
- else {
34928
- dev.updateConfig(cfg);
34929
- }
34930
- }
34931
34784
  // 4) cleanup
34932
34785
  const announced = new Set(manifests.map(m => m.nativeId));
34933
34786
  for (const [nativeId] of this.devices) {
@@ -34973,14 +34826,7 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34973
34826
  // sensors
34974
34827
  for (const s of this.sensorsCfg) {
34975
34828
  const t = s.topics || {};
34976
- [t.contact, t.motion, t.occupancy, t.batteryLevel, t.lowBattery, t.tamper, t.online]
34977
- .filter((x) => !!x && String(x).trim().length > 0)
34978
- .forEach(x => subs.add(String(x)));
34979
- }
34980
- // bypass switches
34981
- for (const b of this.bypassCfg) {
34982
- const t = b.topics || {};
34983
- [t.state]
34829
+ [t.contact, t.motion, t.occupancy, t.batteryLevel, t.lowBattery, t.tamper, t.online, s.bypass?.state]
34984
34830
  .filter((x) => !!x && String(x).trim().length > 0)
34985
34831
  .forEach(x => subs.add(String(x)));
34986
34832
  }
@@ -35129,8 +34975,8 @@ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
35129
34975
  this.console.log(`[Alarm] published target "${payload}" to ${topic}`);
35130
34976
  });
35131
34977
  }
35132
- publishBypass(cfg, payload) {
35133
- const topic = cfg.topics?.control?.trim();
34978
+ publishSensorBypass(cfg, payload) {
34979
+ const topic = cfg.bypass?.control?.trim();
35134
34980
  if (!topic || !this.client) {
35135
34981
  this.console.warn('Bypass topic control o MQTT non configurati.');
35136
34982
  return false;
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.92",
3
+ "version": "1.0.93",
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",