smart-home-engine 0.27.0 → 0.27.2

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.
@@ -1,4 +1,4 @@
1
- import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-DnqoSlvw.js";/*!-----------------------------------------------------------------------------
1
+ import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-sPBEVtGF.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -155,7 +155,7 @@
155
155
  }
156
156
  })();
157
157
  </script>
158
- <script type="module" crossorigin src="/assets/index-DnqoSlvw.js"></script>
158
+ <script type="module" crossorigin src="/assets/index-sPBEVtGF.js"></script>
159
159
  <link rel="modulepreload" crossorigin href="/assets/monaco-langs-BW2J83t5.js">
160
160
  <link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
161
161
  <link rel="stylesheet" crossorigin href="/assets/index-6dbanXAb.css">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-home-engine",
3
- "version": "0.27.0",
3
+ "version": "0.27.2",
4
4
  "description": "Node.js based script runner for use in MQTT based Smart Home environments",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -241,6 +241,28 @@ function sunScheduleEvent(obj, shift) {
241
241
  let mqtt = null;
242
242
  let connected = false;
243
243
 
244
+ // Deferred start — wait for retained MQTT state before running scripts
245
+ let _started = false;
246
+ let _startupTimeout = null;
247
+ let _quietTimer = null;
248
+ const _RETAIN_QUIET_MS = 300; // ms of silence after last retained msg → start
249
+ const _STARTUP_TIMEOUT_MS = 10000; // ms to wait for broker before starting anyway
250
+
251
+ function startOnce(reason) {
252
+ if (_started) return;
253
+ _started = true;
254
+ if (_startupTimeout) {
255
+ clearTimeout(_startupTimeout);
256
+ _startupTimeout = null;
257
+ }
258
+ if (_quietTimer) {
259
+ clearTimeout(_quietTimer);
260
+ _quietTimer = null;
261
+ }
262
+ if (reason) log.info(reason);
263
+ start();
264
+ }
265
+
244
266
  // Wire up the MQTT API: pass the state store and a getter for the live MQTT client.
245
267
  // The getter always returns the current value of `mqtt` (null until connected).
246
268
  require('./web/mqtt-api').init(store, () => mqtt);
@@ -323,6 +345,12 @@ if (config.url) {
323
345
  log.debug('mqtt subscribe #');
324
346
  mqtt.subscribe('#');
325
347
  mqttEventCallbacks.filter((c) => c.event === 'connect').forEach((c) => c.callback());
348
+
349
+ // Arm the quiet-period timer (only needed on first connect, before scripts start)
350
+ if (!_started) {
351
+ if (_quietTimer) clearTimeout(_quietTimer);
352
+ _quietTimer = setTimeout(() => startOnce('mqtt: retained state ready, starting scripts'), _RETAIN_QUIET_MS);
353
+ }
326
354
  });
327
355
 
328
356
  mqtt.on('close', () => {
@@ -339,6 +367,13 @@ if (config.url) {
339
367
 
340
368
  mqtt.on('message', (topic, payload, msg) => {
341
369
  _mqttMsgCount++;
370
+
371
+ // Reset the quiet-period timer while the initial retained-message burst is in flight
372
+ if (!_started && msg.retain && _quietTimer) {
373
+ clearTimeout(_quietTimer);
374
+ _quietTimer = setTimeout(() => startOnce('mqtt: retained state ready, starting scripts'), _RETAIN_QUIET_MS);
375
+ }
376
+
342
377
  if (shedb.handleMqttMessage(topic, payload)) return;
343
378
 
344
379
  const state = require('./lib/parse-payload')(payload);
@@ -428,8 +463,18 @@ if (config.matterStorage) {
428
463
  log.warn('matter controller disabled — set matterStorage in config.json to enable');
429
464
  }
430
465
 
431
- // Start scripts immediately — MQTT retained state will populate the store asynchronously
432
- start();
466
+ // If no broker is configured, start scripts immediately.
467
+ // If a broker is configured, startOnce() fires from the quiet-period timer inside
468
+ // mqtt.on('connect') once the retained-message burst settles, or from the
469
+ // startup-timeout fallback if the broker is unreachable.
470
+ if (config.url) {
471
+ _startupTimeout = setTimeout(() => {
472
+ log.warn('mqtt startup timeout — starting scripts without retained state');
473
+ startOnce();
474
+ }, _STARTUP_TIMEOUT_MS);
475
+ } else {
476
+ start();
477
+ }
433
478
 
434
479
  function stateChange(topic, state, oldState, msg) {
435
480
  subscriptions.forEach((subs) => {
package/src/web/server.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const express = require('express');
4
4
  const path = require('path');
5
- const { spawnSync, spawn } = require('child_process');
5
+ const { spawn } = require('child_process');
6
6
  const semverCompare = require('semantic-compare');
7
7
  const pkg = require('../../package.json');
8
8
  const { router: configRouter } = require('./config-api');
@@ -96,8 +96,10 @@ app.post('/she/check-update', async (req, res) => {
96
96
  app.post('/she/update', (req, res) => {
97
97
  res.json({ ok: true });
98
98
  setTimeout(() => {
99
- spawnSync('sudo', ['npm', 'install', '-g', 'smart-home-engine'], { stdio: 'inherit' });
100
- _systemdRestart();
99
+ // Use async spawn so the HTTP server (and event loop) remain responsive
100
+ // while npm runs. spawnSync would block all HTTP polling from the UI.
101
+ const child = spawn('sudo', ['npm', 'install', '-g', 'smart-home-engine'], { stdio: 'inherit' });
102
+ child.on('close', () => _systemdRestart());
101
103
  }, 200);
102
104
  });
103
105