Здравствуйте! Сегодня выходной день, поэтому сотрудники техподдержки ответят вам в рабочий день.
Пока что я, автоматический помощник, проанализировал ваш вопрос и постарался найти решение:
Судя по скриншоту, речь о системных топиках контроллера (например, hwmon/power_status/working on battery, battery/controls/Percentage, Voltage и т.п.), которые публикуются очень часто и «забивают» MQTT.
1. Общий принцип: публикация только при изменении
У стандартных системных драйверов Wiren Board (температура, питание, батарея и т.п.) обычно уже используется публикация «по изменению» плюс периодическая републикация с достаточно редким интервалом. Сильно «дребезжать» они не должны, если данные реально не меняются.
Но есть нюанс:
- некоторые параметры (например, состояния питания, батареи) опрашиваются с небольшим периодом (1–5 с) и публикуются каждый раз, даже при малой дельте;
- для системных устройств нет штатного «tolerance»/«deadband» в конфиге, который можно просто подкрутить через UI.
Прямо на уровне уже опубликованных топиков сделать фильтр «отправлять только при изменении» нельзя — нужен либо:
- фильтрующий MQTT‑посредник, либо
- своя «виртуальная» прослойка в
wb-rules.
2. Практическое решение через wb-rules
Идея:
- не подписывать внешние системы на «сырой» топик контроллера,
- а создать свои виртуальные контролы, куда правило будет пересылать значения только при изменении выше порога и/или с редкой периодичностью.
Пример скрипта wb-rules (для процента батареи; по аналогии для тока, напряжения и т.д.):
var lastBattery = null;
var lastSent = 0;
var MIN_DELTA = 1.0; // минимальная дельта, %, чтобы послать обновление
var MIN_PERIOD = 300000; // минимальный период, мс (здесь 5 минут)
defineVirtualDevice("filtered_battery", {
title: "Filtered battery",
cells: {
Percentage: {
type: "value",
units: "%",
initial: 0
}
}
});
defineRule("filter_battery_percentage", {
whenChanged: "battery/controls/Percentage",
then: function (newValue, devName, cellName) {
var now = Date.now();
var v = parseFloat(newValue);
if (isNaN(v)) return;
if (lastBattery === null) {
lastBattery = v;
lastSent = now;
dev["filtered_battery"]["Percentage"] = v;
return;
}
var delta = Math.abs(v - lastBattery);
// Условие отправки: изменилась больше, чем на MIN_DELTA,
// ИЛИ прошло больше MIN_PERIOD с прошлой отправки
if (delta >= MIN_DELTA || (now - lastSent) >= MIN_PERIOD) {
dev["filtered_battery"]["Percentage"] = v;
lastBattery = v;
lastSent = now;
}
}
});
Подписывать внешние системы (Home Assistant, Node-RED и т.д.) уже на топик:
/devices/filtered_battery/controls/Percentage
Аналогично можно сделать скрипты с разными MIN_DELTA и MIN_PERIOD для Current, Voltage, Charging, либо собрать всё в одно правило с несколькими переменными состояния.
3. Что ещё можно сделать на уровне брокера/клиента
Если проблема именно в сети/клиенте, а не в логике:
- В некоторых MQTT‑клиентах есть опция «process only changed values» – можно реализовать аналогичный фильтр уже на стороне приёмника.
- Если вы используете внешний брокер вместо встроенного Mosquitto, у части брокеров/плагинов есть поддержка «suppression of unchanged messages» или агрегации сообщений.
4. Имеет ли смысл «прикручивать» это к системным устройствам напрямую
На текущий момент в документации Wiren Board не описано штатной настройки порога изменения/частоты публикации именно для системных датчиков батареи и питания через UI или конфиги драйвера. Поэтому рекомендованный путь — именно «виртуальное устройство + правило», как выше.
Если напишете:
- модель контроллера (WB6/WB7/WB8),
- версии
wb-mqtt-confed, wb-rules и прошивки,
инженеры в будни смогут дополнительно подсказать, нет ли в вашей версии уже каких‑то скрытых опций по системным устройствам.
Примечание: Я — искусственный интеллект, а не человек. В моих ответах могут быть неточности.