@rfranzoi/scrypted-mqtt-securitysystem 1.0.44 → 1.0.46

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.
@@ -34024,28 +34024,46 @@ 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
+ })();
34027
34060
  var __importDefault = (this && this.__importDefault) || function (mod) {
34028
34061
  return (mod && mod.__esModule) ? mod : { "default": mod };
34029
34062
  };
34030
34063
  Object.defineProperty(exports, "__esModule", ({ value: true }));
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, deviceManager, } = sdk;
34064
+ const sdk_1 = __importStar(__webpack_require__(/*! @scrypted/sdk */ "./node_modules/@scrypted/sdk/dist/src/index.js"));
34048
34065
  const mqtt_1 = __importDefault(__webpack_require__(/*! mqtt */ "./node_modules/mqtt/build/index.js"));
34066
+ const { systemManager, deviceManager } = sdk_1.default;
34049
34067
  /** utils */
34050
34068
  function truthy(v) {
34051
34069
  if (!v)
@@ -34065,13 +34083,12 @@ function normalize(s) {
34065
34083
  function clamp(n, min, max) {
34066
34084
  return Math.max(min, Math.min(max, n));
34067
34085
  }
34068
- /** SecuritySystem outgoing defaults (PAI-like)
34069
- * Nota: usare number come chiave evita stranezze con gli enum in TS. */
34086
+ /** SecuritySystem outgoing defaults (PAI-like) */
34070
34087
  const DEFAULT_OUTGOING = {
34071
- [SecuritySystemMode.Disarmed]: 'disarm',
34072
- [SecuritySystemMode.HomeArmed]: 'arm_home',
34073
- [SecuritySystemMode.AwayArmed]: 'arm_away',
34074
- [SecuritySystemMode.NightArmed]: 'arm_night',
34088
+ [sdk_1.SecuritySystemMode.Disarmed]: 'disarm',
34089
+ [sdk_1.SecuritySystemMode.HomeArmed]: 'arm_home',
34090
+ [sdk_1.SecuritySystemMode.AwayArmed]: 'arm_away',
34091
+ [sdk_1.SecuritySystemMode.NightArmed]: 'arm_night',
34075
34092
  };
34076
34093
  /** Parse incoming payload -> final mode (ignore transition states) */
34077
34094
  function payloadToMode(payload) {
@@ -34079,23 +34096,36 @@ function payloadToMode(payload) {
34079
34096
  return;
34080
34097
  const p = normalize(payload.toString());
34081
34098
  if (['disarm', 'disarmed', 'off', '0', 'idle', 'ready'].includes(p))
34082
- return SecuritySystemMode.Disarmed;
34099
+ return sdk_1.SecuritySystemMode.Disarmed;
34083
34100
  if (['arm_home', 'home', 'stay', 'armed_home'].includes(p))
34084
- return SecuritySystemMode.HomeArmed;
34101
+ return sdk_1.SecuritySystemMode.HomeArmed;
34085
34102
  if (['arm_away', 'away', 'armed_away', 'away_armed'].includes(p))
34086
- return SecuritySystemMode.AwayArmed;
34103
+ return sdk_1.SecuritySystemMode.AwayArmed;
34087
34104
  if (['arm_night', 'night', 'armed_night', 'sleep', 'arm_sleep', 'armed_sleep'].includes(p))
34088
- return SecuritySystemMode.NightArmed;
34105
+ return sdk_1.SecuritySystemMode.NightArmed;
34089
34106
  // transitori: non cambiano il mode
34090
34107
  if (['entry_delay', 'exit_delay', 'pending', 'arming', 'disarming'].includes(p))
34091
34108
  return undefined;
34092
34109
  return undefined;
34093
34110
  }
34094
- class BaseMqttSensor extends ScryptedDeviceBase {
34111
+ class BaseMqttSensor extends sdk_1.ScryptedDeviceBase {
34095
34112
  constructor(nativeId, cfg) {
34096
34113
  super(nativeId);
34097
34114
  this.cfg = cfg;
34098
34115
  }
34116
+ /** setter centralizzato: cambia lo stato SOLO se diverso e poi emette l'evento relativo */
34117
+ setAndEmit(prop, val, iface) {
34118
+ const prev = this[prop];
34119
+ if (prev === val)
34120
+ return;
34121
+ this[prop] = val;
34122
+ try {
34123
+ this.onDeviceEvent(iface, val);
34124
+ }
34125
+ catch (e) {
34126
+ this.console?.warn?.('onDeviceEvent error', iface, e);
34127
+ }
34128
+ }
34099
34129
  /** Called by parent on each MQTT message */
34100
34130
  handleMqtt(topic, payload) {
34101
34131
  const p = payload?.toString() ?? '';
@@ -34103,56 +34133,80 @@ class BaseMqttSensor extends ScryptedDeviceBase {
34103
34133
  // online
34104
34134
  if (topic === this.cfg.topics.online) {
34105
34135
  if (truthy(np) || np === 'online')
34106
- this.online = true;
34136
+ this.setAndEmit('online', true, sdk_1.ScryptedInterface.Online);
34107
34137
  if (falsy(np) || np === 'offline')
34108
- this.online = false;
34138
+ this.setAndEmit('online', false, sdk_1.ScryptedInterface.Online);
34109
34139
  }
34110
34140
  // tamper
34111
34141
  if (topic === this.cfg.topics.tamper) {
34112
34142
  if (truthy(np) || ['tamper', 'intrusion', 'cover', 'motion', 'magnetic'].includes(np)) {
34113
- this.tampered = ['cover', 'intrusion', 'motion', 'magnetic'].find(x => x === np) || true;
34143
+ const value = ['cover', 'intrusion', 'motion', 'magnetic'].find(x => x === np) || true;
34144
+ this.setAndEmit('tampered', value, sdk_1.ScryptedInterface.TamperSensor);
34114
34145
  }
34115
34146
  else if (falsy(np)) {
34116
- this.tampered = false;
34147
+ this.setAndEmit('tampered', false, sdk_1.ScryptedInterface.TamperSensor);
34117
34148
  }
34118
34149
  }
34119
34150
  // battery
34120
34151
  if (topic === this.cfg.topics.batteryLevel) {
34121
34152
  const n = clamp(parseFloat(p), 0, 100);
34122
34153
  if (isFinite(n))
34123
- this.batteryLevel = n;
34154
+ this.setAndEmit('batteryLevel', n, sdk_1.ScryptedInterface.Battery);
34124
34155
  }
34125
34156
  else if (topic === this.cfg.topics.lowBattery && !this.cfg.topics.batteryLevel) {
34126
- // se abbiamo SOLO lowBattery (bool):
34127
- this.batteryLevel = truthy(np) ? 10 : 100;
34157
+ // Solo se abbiamo lowBattery (booleano) ma NON batteryLevel:
34158
+ this.setAndEmit('batteryLevel', truthy(np) ? 10 : 100, sdk_1.ScryptedInterface.Battery);
34128
34159
  }
34129
34160
  // primary handled by subclasses
34130
34161
  this.handlePrimary(topic, np, p);
34131
34162
  }
34132
34163
  }
34133
34164
  class ContactMqttSensor extends BaseMqttSensor {
34134
- handlePrimary(topic, np) {
34165
+ handlePrimary(topic, np, _raw) {
34135
34166
  if (topic === this.cfg.topics.contact) {
34136
- this.entryOpen = truthy(np);
34167
+ const v = truthy(np);
34168
+ // usa il setter che emette l'evento di EntrySensor
34169
+ this.setAndEmit?.('entryOpen', v, sdk_1.ScryptedInterface.EntrySensor);
34170
+ // fallback per sicurezza (in alcune minifiche setAndEmit non è visibile):
34171
+ if (this.setAndEmit === undefined) {
34172
+ if (this.entryOpen !== v) {
34173
+ this.entryOpen = v;
34174
+ this.onDeviceEvent(sdk_1.ScryptedInterface.EntrySensor, v);
34175
+ }
34176
+ }
34137
34177
  }
34138
34178
  }
34139
34179
  }
34140
34180
  class MotionMqttSensor extends BaseMqttSensor {
34141
- handlePrimary(topic, np) {
34181
+ handlePrimary(topic, np, _raw) {
34142
34182
  if (topic === this.cfg.topics.motion) {
34143
- this.motionDetected = truthy(np);
34183
+ const v = truthy(np);
34184
+ this.setAndEmit?.('motionDetected', v, sdk_1.ScryptedInterface.MotionSensor);
34185
+ if (this.setAndEmit === undefined) {
34186
+ if (this.motionDetected !== v) {
34187
+ this.motionDetected = v;
34188
+ this.onDeviceEvent(sdk_1.ScryptedInterface.MotionSensor, v);
34189
+ }
34190
+ }
34144
34191
  }
34145
34192
  }
34146
34193
  }
34147
34194
  class OccupancyMqttSensor extends BaseMqttSensor {
34148
- handlePrimary(topic, np) {
34195
+ handlePrimary(topic, np, _raw) {
34149
34196
  if (topic === this.cfg.topics.occupancy) {
34150
- this.occupied = truthy(np);
34197
+ const v = truthy(np);
34198
+ this.setAndEmit?.('occupied', v, sdk_1.ScryptedInterface.OccupancySensor);
34199
+ if (this.setAndEmit === undefined) {
34200
+ if (this.occupied !== v) {
34201
+ this.occupied = v;
34202
+ this.onDeviceEvent(sdk_1.ScryptedInterface.OccupancySensor, v);
34203
+ }
34204
+ }
34151
34205
  }
34152
34206
  }
34153
34207
  }
34154
34208
  /** ----------------- Main Plugin ----------------- */
34155
- class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34209
+ class ParadoxMqttSecuritySystem extends sdk_1.ScryptedDeviceBase {
34156
34210
  constructor() {
34157
34211
  super();
34158
34212
  // sensor management
@@ -34161,26 +34215,26 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34161
34215
  // (facoltativo) Imposta il device type in UI
34162
34216
  setTimeout(() => {
34163
34217
  try {
34164
- systemManager.getDeviceById(this.id)?.setType?.(ScryptedDeviceType.SecuritySystem);
34218
+ systemManager.getDeviceById(this.id)?.setType?.(sdk_1.ScryptedDeviceType.SecuritySystem);
34165
34219
  }
34166
34220
  catch { }
34167
34221
  });
34168
34222
  // Default state
34169
34223
  this.securitySystemState = this.securitySystemState || {
34170
- mode: SecuritySystemMode.Disarmed,
34224
+ mode: sdk_1.SecuritySystemMode.Disarmed,
34171
34225
  supportedModes: [
34172
- SecuritySystemMode.Disarmed,
34173
- SecuritySystemMode.HomeArmed,
34174
- SecuritySystemMode.AwayArmed,
34175
- SecuritySystemMode.NightArmed,
34226
+ sdk_1.SecuritySystemMode.Disarmed,
34227
+ sdk_1.SecuritySystemMode.HomeArmed,
34228
+ sdk_1.SecuritySystemMode.AwayArmed,
34229
+ sdk_1.SecuritySystemMode.NightArmed,
34176
34230
  ],
34177
34231
  };
34178
34232
  this.online = this.online ?? false;
34179
34233
  // Load sensors config and announce devices
34180
34234
  this.loadSensorsFromStorage();
34181
- this.discoverSensors().catch((e) => this.console.error('discoverSensors error', e));
34235
+ this.discoverSensors().catch(e => this.console.error('discoverSensors error', e));
34182
34236
  // Connect on start
34183
- this.connectMqtt().catch((e) => this.console.error('MQTT connect error:', e));
34237
+ this.connectMqtt().catch(e => this.console.error('MQTT connect error:', e));
34184
34238
  // chiusura pulita del client MQTT ai reload/stop del plugin
34185
34239
  try {
34186
34240
  process.once('SIGTERM', () => { try {
@@ -34362,22 +34416,22 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34362
34416
  const manifests = this.sensorsCfg.map(cfg => {
34363
34417
  const nativeId = `sensor:${cfg.id}`;
34364
34418
  const t = cfg.topics || {};
34365
- const interfaces = [ScryptedInterface.Online];
34419
+ const interfaces = [sdk_1.ScryptedInterface.Online];
34366
34420
  // Tamper solo se c'è un topic tamper
34367
34421
  if (t.tamper)
34368
- interfaces.push(ScryptedInterface.TamperSensor);
34422
+ interfaces.push(sdk_1.ScryptedInterface.TamperSensor);
34369
34423
  // Interfaccia primaria
34370
34424
  if (cfg.kind === 'contact')
34371
- interfaces.unshift(ScryptedInterface.EntrySensor);
34425
+ interfaces.unshift(sdk_1.ScryptedInterface.EntrySensor);
34372
34426
  else if (cfg.kind === 'motion')
34373
- interfaces.unshift(ScryptedInterface.MotionSensor);
34427
+ interfaces.unshift(sdk_1.ScryptedInterface.MotionSensor);
34374
34428
  else
34375
- interfaces.unshift(ScryptedInterface.OccupancySensor);
34429
+ interfaces.unshift(sdk_1.ScryptedInterface.OccupancySensor);
34376
34430
  // Battery solo se previsto
34377
34431
  if (t.batteryLevel || t.lowBattery) {
34378
- interfaces.push(ScryptedInterface.Battery);
34432
+ interfaces.push(sdk_1.ScryptedInterface.Battery);
34379
34433
  }
34380
- return { nativeId, name: cfg.name, type: ScryptedDeviceType.Sensor, interfaces };
34434
+ return { nativeId, name: cfg.name, type: sdk_1.ScryptedDeviceType.Sensor, interfaces };
34381
34435
  });
34382
34436
  // 2) Annuncio
34383
34437
  const dmAny = deviceManager;
@@ -34411,6 +34465,10 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34411
34465
  const hasBattery = !!(cfg.topics.batteryLevel || cfg.topics.lowBattery);
34412
34466
  if (hasBattery && dev.batteryLevel === undefined) {
34413
34467
  dev.batteryLevel = 100;
34468
+ try {
34469
+ dev.onDeviceEvent(sdk_1.ScryptedInterface.Battery, 100);
34470
+ }
34471
+ catch { }
34414
34472
  }
34415
34473
  }
34416
34474
  // 4) Rimuovi quelli spariti
@@ -34488,6 +34546,10 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34488
34546
  client.on('connect', () => {
34489
34547
  this.console.log('MQTT connected');
34490
34548
  this.online = true;
34549
+ try {
34550
+ this.onDeviceEvent(sdk_1.ScryptedInterface.Online, true);
34551
+ }
34552
+ catch { }
34491
34553
  if (subs.length) {
34492
34554
  client.subscribe(subs, { qos: 0 }, (err) => {
34493
34555
  if (err)
@@ -34496,7 +34558,14 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34496
34558
  }
34497
34559
  });
34498
34560
  client.on('reconnect', () => this.console.log('MQTT reconnecting...'));
34499
- client.on('close', () => { this.console.log('MQTT closed'); this.online = false; });
34561
+ client.on('close', () => {
34562
+ this.console.log('MQTT closed');
34563
+ this.online = false;
34564
+ try {
34565
+ this.onDeviceEvent(sdk_1.ScryptedInterface.Online, false);
34566
+ }
34567
+ catch { }
34568
+ });
34500
34569
  client.on('error', (e) => { this.console.error('MQTT error', e); });
34501
34570
  client.on('message', (topic, payload) => {
34502
34571
  try {
@@ -34504,36 +34573,59 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34504
34573
  const np = normalize(p);
34505
34574
  // ---- Alarm handling ----
34506
34575
  if (topic === tOnline) {
34507
- if (truthy(np) || np === 'online')
34576
+ if (truthy(np) || np === 'online') {
34508
34577
  this.online = true;
34509
- if (falsy(np) || np === 'offline')
34578
+ try {
34579
+ this.onDeviceEvent(sdk_1.ScryptedInterface.Online, true);
34580
+ }
34581
+ catch { }
34582
+ }
34583
+ if (falsy(np) || np === 'offline') {
34510
34584
  this.online = false;
34585
+ try {
34586
+ this.onDeviceEvent(sdk_1.ScryptedInterface.Online, false);
34587
+ }
34588
+ catch { }
34589
+ }
34511
34590
  return;
34512
34591
  }
34513
34592
  if (topic === tTamper) {
34514
34593
  if (truthy(np) || ['tamper', 'intrusion', 'cover'].includes(np)) {
34515
- this.tampered = ['cover', 'intrusion'].find(x => x === np) || true;
34594
+ const val = ['cover', 'intrusion'].find(x => x === np) || true;
34595
+ this.tampered = val;
34596
+ try {
34597
+ this.onDeviceEvent(sdk_1.ScryptedInterface.TamperSensor, val);
34598
+ }
34599
+ catch { }
34516
34600
  }
34517
34601
  else if (falsy(np)) {
34518
34602
  this.tampered = false;
34603
+ try {
34604
+ this.onDeviceEvent(sdk_1.ScryptedInterface.TamperSensor, false);
34605
+ }
34606
+ catch { }
34519
34607
  }
34520
34608
  return;
34521
34609
  }
34522
34610
  if (topic === tCurrent) {
34523
34611
  const mode = payloadToMode(payload);
34524
34612
  const isAlarm = ['alarm', 'triggered'].includes(np);
34525
- const current = this.securitySystemState || { mode: SecuritySystemMode.Disarmed };
34613
+ const current = this.securitySystemState || { mode: sdk_1.SecuritySystemMode.Disarmed };
34526
34614
  const newState = {
34527
34615
  mode: mode ?? current.mode,
34528
34616
  supportedModes: current.supportedModes ?? [
34529
- SecuritySystemMode.Disarmed,
34530
- SecuritySystemMode.HomeArmed,
34531
- SecuritySystemMode.AwayArmed,
34532
- SecuritySystemMode.NightArmed,
34617
+ sdk_1.SecuritySystemMode.Disarmed,
34618
+ sdk_1.SecuritySystemMode.HomeArmed,
34619
+ sdk_1.SecuritySystemMode.AwayArmed,
34620
+ sdk_1.SecuritySystemMode.NightArmed,
34533
34621
  ],
34534
34622
  triggered: isAlarm || undefined,
34535
34623
  };
34536
34624
  this.securitySystemState = newState;
34625
+ try {
34626
+ this.onDeviceEvent(sdk_1.ScryptedInterface.SecuritySystem, newState);
34627
+ }
34628
+ catch { }
34537
34629
  return;
34538
34630
  }
34539
34631
  if (topic === tTarget) {
@@ -34573,17 +34665,17 @@ class ParadoxMqttSecuritySystem extends ScryptedDeviceBase {
34573
34665
  this.publishSetTarget(payload);
34574
34666
  }
34575
34667
  async disarmSecuritySystem() {
34576
- const payload = this.getOutgoing(SecuritySystemMode.Disarmed);
34668
+ const payload = this.getOutgoing(sdk_1.SecuritySystemMode.Disarmed);
34577
34669
  this.console.log('disarmSecuritySystem ->', payload);
34578
- this.pendingTarget = SecuritySystemMode.Disarmed;
34670
+ this.pendingTarget = sdk_1.SecuritySystemMode.Disarmed;
34579
34671
  this.publishSetTarget(payload);
34580
34672
  }
34581
34673
  getOutgoing(mode) {
34582
34674
  const map = {
34583
- [SecuritySystemMode.Disarmed]: this.storage.getItem('payloadDisarm') || DEFAULT_OUTGOING[SecuritySystemMode.Disarmed],
34584
- [SecuritySystemMode.HomeArmed]: this.storage.getItem('payloadHome') || DEFAULT_OUTGOING[SecuritySystemMode.HomeArmed],
34585
- [SecuritySystemMode.AwayArmed]: this.storage.getItem('payloadAway') || DEFAULT_OUTGOING[SecuritySystemMode.AwayArmed],
34586
- [SecuritySystemMode.NightArmed]: this.storage.getItem('payloadNight') || DEFAULT_OUTGOING[SecuritySystemMode.NightArmed],
34675
+ [sdk_1.SecuritySystemMode.Disarmed]: this.storage.getItem('payloadDisarm') || DEFAULT_OUTGOING[sdk_1.SecuritySystemMode.Disarmed],
34676
+ [sdk_1.SecuritySystemMode.HomeArmed]: this.storage.getItem('payloadHome') || DEFAULT_OUTGOING[sdk_1.SecuritySystemMode.HomeArmed],
34677
+ [sdk_1.SecuritySystemMode.AwayArmed]: this.storage.getItem('payloadAway') || DEFAULT_OUTGOING[sdk_1.SecuritySystemMode.AwayArmed],
34678
+ [sdk_1.SecuritySystemMode.NightArmed]: this.storage.getItem('payloadNight') || DEFAULT_OUTGOING[sdk_1.SecuritySystemMode.NightArmed],
34587
34679
  };
34588
34680
  return map[mode];
34589
34681
  }
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.44",
3
+ "version": "1.0.46",
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",