Skip to content

Commit a4c43a3

Browse files
committed
fix(WebServer): fix threshold alarm function not working properly
1 parent f27fead commit a4c43a3

2 files changed

Lines changed: 43 additions & 26 deletions

File tree

Tools/WebServer/monitor.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,22 @@ def cleanup_audio_meter(device):
252252
logger.debug(f"Audio recorder cleanup: {e}")
253253

254254

255-
def check_threshold_alarm(device, value, current_mode):
256-
"""Check if value exceeds threshold and trigger alarm."""
255+
def check_threshold_alarm(device):
256+
"""Check if threshold is exceeded and trigger alarm.
257+
258+
The threshold check is independent of the current monitor mode.
259+
It fetches the value based on device.threshold_mode separately.
260+
"""
257261
if not device.threshold_enable:
258262
return
259263

260-
if current_mode != device.threshold_mode:
264+
threshold_mode = device.threshold_mode
265+
if not threshold_mode or threshold_mode == "none":
261266
return
262267

263-
if value is None:
268+
# Get value based on threshold_mode (independent of monitor mode)
269+
value, error = get_monitor_value(threshold_mode)
270+
if error or value is None:
264271
return
265272

266273
now = time.time()
@@ -271,7 +278,7 @@ def check_threshold_alarm(device, value, current_mode):
271278
serial_write_direct(device, cmd)
272279
logger = logging.getLogger(__name__)
273280
logger.info(
274-
f"Threshold alarm triggered: {value:.1f}% > {device.threshold_value}%"
281+
f"Threshold alarm triggered: {threshold_mode}={value:.1f}% > {device.threshold_value}%"
275282
)
276283

277284

@@ -404,9 +411,8 @@ def monitor_tick():
404411
# 更新 legacy last_percent (用于兼容)
405412
device.last_percent = percent_0 if percent_0 is not None else (percent_1 or 0)
406413

407-
# 阈值报警检查 (使用 CH0 的值)
408-
if percent_0 is not None:
409-
check_threshold_alarm(device, percent_0, mode_0)
414+
# 阈值报警检查 (独立于监控模式)
415+
check_threshold_alarm(device)
410416

411417
return monitor_tick
412418

Tools/WebServer/tests/test_monitor.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"""
99

1010
import time
11-
from unittest.mock import MagicMock
11+
from unittest.mock import MagicMock, patch
1212

1313

1414
class TestGetMonitorValue:
@@ -280,49 +280,56 @@ def test_threshold_disabled(self):
280280

281281
device = DeviceState("test", "Test")
282282
device.threshold_enable = False
283+
device.threshold_mode = "cpu-usage"
283284
# Should not raise any exception
284-
check_threshold_alarm(device, 100, "cpu-usage")
285+
check_threshold_alarm(device)
285286

286-
def test_threshold_mode_mismatch(self):
287-
"""Test when mode doesn't match threshold mode."""
287+
def test_threshold_mode_none(self):
288+
"""Test when threshold mode is none."""
288289
from monitor import check_threshold_alarm
289290
from state import DeviceState
290291

291292
device = DeviceState("test", "Test")
292293
device.threshold_enable = True
293-
device.threshold_mode = "cpu-usage"
294-
# Should not trigger alarm for different mode
295-
check_threshold_alarm(device, 100, "mem-usage")
294+
device.threshold_mode = "none"
295+
# Should not trigger alarm
296+
check_threshold_alarm(device)
296297

297-
def test_threshold_value_none(self):
298-
"""Test when value is None."""
298+
@patch("monitor.get_monitor_value")
299+
def test_threshold_value_none(self, mock_get_value):
300+
"""Test when get_monitor_value returns None."""
299301
from monitor import check_threshold_alarm
300302
from state import DeviceState
301303

304+
mock_get_value.return_value = (None, "Error")
302305
device = DeviceState("test", "Test")
303306
device.threshold_enable = True
304307
device.threshold_mode = "cpu-usage"
305308
# Should not raise any exception
306-
check_threshold_alarm(device, None, "cpu-usage")
309+
check_threshold_alarm(device)
307310

308-
def test_threshold_below_value(self):
311+
@patch("monitor.get_monitor_value")
312+
def test_threshold_below_value(self, mock_get_value):
309313
"""Test when value is below threshold."""
310314
from monitor import check_threshold_alarm
311315
from state import DeviceState
312316

317+
mock_get_value.return_value = (50, None)
313318
device = DeviceState("test", "Test")
314319
device.threshold_enable = True
315320
device.threshold_mode = "cpu-usage"
316321
device.threshold_value = 80
317322
device.last_alarm_time = 0
318323
# Should not trigger alarm
319-
check_threshold_alarm(device, 50, "cpu-usage")
324+
check_threshold_alarm(device)
320325

321-
def test_threshold_triggered(self):
326+
@patch("monitor.get_monitor_value")
327+
def test_threshold_triggered(self, mock_get_value):
322328
"""Test when threshold is exceeded."""
323329
from monitor import check_threshold_alarm
324330
from state import DeviceState
325331

332+
mock_get_value.return_value = (90, None)
326333
device = DeviceState("test", "Test")
327334
device.threshold_enable = True
328335
device.threshold_mode = "cpu-usage"
@@ -332,15 +339,17 @@ def test_threshold_triggered(self):
332339
device.last_alarm_time = 0
333340
device.ser = None # No serial, but should still update last_alarm_time
334341

335-
check_threshold_alarm(device, 90, "cpu-usage")
342+
check_threshold_alarm(device)
336343
# last_alarm_time should be updated
337344
assert device.last_alarm_time > 0
338345

339-
def test_threshold_cooldown(self):
346+
@patch("monitor.get_monitor_value")
347+
def test_threshold_cooldown(self, mock_get_value):
340348
"""Test threshold cooldown period."""
341349
from monitor import check_threshold_alarm
342350
from state import DeviceState
343351

352+
mock_get_value.return_value = (90, None)
344353
device = DeviceState("test", "Test")
345354
device.threshold_enable = True
346355
device.threshold_mode = "cpu-usage"
@@ -351,15 +360,17 @@ def test_threshold_cooldown(self):
351360
device.ser = None
352361

353362
old_time = device.last_alarm_time
354-
check_threshold_alarm(device, 90, "cpu-usage")
363+
check_threshold_alarm(device)
355364
# Should not update due to cooldown
356365
assert device.last_alarm_time == old_time
357366

358-
def test_threshold_with_serial(self):
367+
@patch("monitor.get_monitor_value")
368+
def test_threshold_with_serial(self, mock_get_value):
359369
"""Test threshold alarm with serial port."""
360370
from monitor import check_threshold_alarm
361371
from state import DeviceState
362372

373+
mock_get_value.return_value = (90, None)
363374
device = DeviceState("test", "Test")
364375
device.threshold_enable = True
365376
device.threshold_mode = "cpu-usage"
@@ -370,7 +381,7 @@ def test_threshold_with_serial(self):
370381
device.ser = MagicMock()
371382
device.ser.isOpen.return_value = True
372383

373-
check_threshold_alarm(device, 90, "cpu-usage")
384+
check_threshold_alarm(device)
374385
assert device.last_alarm_time > 0
375386

376387

0 commit comments

Comments
 (0)