Создаю другую тему по этом вопросу.
Проверьте, что режиме Modbus TCP шлюза включен клиент в настройках модуля Properties → Server Parameters → Allow Modbus TCP Client.
так до обновления на тестовую прошивку wirenboard все работало ! сегодня правда еще раз обновление поставлю может уже проблемма локализованна
так этот параметр как был выставлен так и стоит !
Запишите значение яркости напрямую в шлюз с компьютера, минуя контроллер (любым Modbus-TCP клиентом, например modpoll или Modbus Poll) — в тот же holding-регистр, что и включённый канал (Device 1/2 Brightness), несколько раз подряд. И посмотрите:
-
если светильник при прямой записи реагирует, а из веб-интерфейса контроллера — нет, значит дело в драйвере, и это нам сильно поможет;
-
если не реагирует и напрямую — смотрим уже в сторону самого шлюза.
И для полноты картины уточните, пожалуйста: с какой версии прошивки вы обновлялись (какой релиз стоял раньше, когда всё работало)? Это поможет точнее локализовать, что именно изменилось.
Вопрос можно закрывать, ошибка была в правиле:
не верное правило
============================================
// ВИРТУАЛЬНОЕ УСТРОЙСТВО
// ============================================
defineVirtualDevice(“dali_light_control”, {
title: “DALI Light Control”,
cells: {
power_0: { type: “switch”, value: false },
brightness_0: { type: “range”, value: 0, max: 100, min: 0 },
power_1: { type: “switch”, value: false },
brightness_1: { type: “range”, value: 0, max: 100, min: 0 },
power_2: { type: “switch”, value: false },
brightness_2: { type: “range”, value: 0, max: 100, min: 0 }
}
});
// ============================================
// ПЕРЕМЕННЫЕ
// ============================================
var brightnessPercent_0 = 100;
var brightnessPercent_1 = 100;
var brightnessPercent_2 = 100;
var updating = false;
// ============================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ С ОБРАБОТКОЙ ОШИБОК
// ============================================
function safeFloat(value, defaultValue) {
defaultValue = (defaultValue === undefined) ? 0 : defaultValue;
try {
if (value === null || value === undefined) return defaultValue;
if (typeof value === ‘number’) return value;
if (typeof value === ‘string’) {
var trimmed = value.trim();
if (trimmed === ‘’) return defaultValue;
var num = parseFloat(trimmed);
return isNaN(num) ? defaultValue : num;
}
return defaultValue;
} catch(e) {
log("Error in safeFloat: " + e);
return defaultValue;
}
}
function toBool(value) {
try {
if (value === null || value === undefined) return false;
if (typeof value === ‘boolean’) return value;
if (typeof value === ‘number’) return value > 0;
if (typeof value === ‘string’) {
var trimmed = value.trim();
if (trimmed === ‘’) return false;
return trimmed === ‘1’ || trimmed === ‘true’ || trimmed === ‘on’ || trimmed === ‘ON’;
}
return false;
} catch(e) {
log("Error in toBool: " + e);
return false;
}
}
function toDaliValue(power, brightness) {
var powerBool = toBool(power);
var bright = safeFloat(brightness, 0);
bright = Math.min(100, Math.max(0, bright));
return powerBool ? Math.round(bright * 254 / 100) : 0;
}
// ============================================
// MQTT ПУБЛИКАЦИЯ
// ============================================
function publishState() {
try {
publish(“/devices/dali_light_control/controls/power_0”, String(toBool(dev[“dali_light_control/power_0”]) ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_0”, String(safeFloat(dev[“dali_light_control/brightness_0”], 0)), { retain: true });
publish(“/devices/dali_light_control/controls/power_1”, String(toBool(dev[“dali_light_control/power_1”]) ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_1”, String(safeFloat(dev[“dali_light_control/brightness_1”], 0)), { retain: true });
publish(“/devices/dali_light_control/controls/power_2”, String(toBool(dev[“dali_light_control/power_2”]) ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_2”, String(safeFloat(dev[“dali_light_control/brightness_2”], 0)), { retain: true });
} catch(e) {
log("Error in publishState: " + e);
}
}
// ============================================
// ПРАВИЛО: Виртуальное → DALI
// ============================================
defineRule(“virtual_to_dali”, {
whenChanged: [
“dali_light_control/power_0”,
“dali_light_control/brightness_0”,
“dali_light_control/power_1”,
“dali_light_control/brightness_1”,
“dali_light_control/power_2”,
“dali_light_control/brightness_2”
],
then: function() {
if (updating) return;
updating = true;
try {
// Канал 0
var bright0 = safeFloat(dev[“dali_light_control/brightness_0”], brightnessPercent_0);
if (bright0 >= 0) brightnessPercent_0 = bright0;
var daliValue_0 = toDaliValue(dev[“dali_light_control/power_0”], brightnessPercent_0);
dev[“dali_logic_lite_ps_x1_1/Device 0 Brightness”] = Math.max(0, Math.min(254, daliValue_0));
// Канал 1
var bright1 = safeFloat(dev["dali_light_control/brightness_1"], brightnessPercent_1);
if (bright1 >= 0) brightnessPercent_1 = bright1;
var daliValue_1 = toDaliValue(dev["dali_light_control/power_1"], brightnessPercent_1);
dev["dali_logic_lite_ps_x1_1/Device 1 Brightness"] = Math.max(0, Math.min(254, daliValue_1));
// Канал 2
var bright2 = safeFloat(dev["dali_light_control/brightness_2"], brightnessPercent_2);
if (bright2 >= 0) brightnessPercent_2 = bright2;
var daliValue_2 = toDaliValue(dev["dali_light_control/power_2"], brightnessPercent_2);
dev["dali_logic_lite_ps_x1_1/Device 2 Brightness"] = Math.max(0, Math.min(254, daliValue_2));
publishState();
} catch(e) {
log("Error in virtual_to_dali: " + e);
}
updating = false;
}
});
// ============================================
// ПРАВИЛО: DALI → Виртуальное
// ============================================
defineRule(“dali_to_virtual”, {
whenChanged: [
“dali_logic_lite_ps_x1_1/Device 0 Brightness”,
“dali_logic_lite_ps_x1_1/Device 1 Brightness”,
“dali_logic_lite_ps_x1_1/Device 2 Brightness”
],
then: function() {
if (updating) return;
updating = true;
try {
// Канал 0
var dali0 = safeFloat(dev[“dali_logic_lite_ps_x1_1/Device 0 Brightness”], 0);
var percent0 = Math.round(dali0 * 100 / 254);
percent0 = Math.max(0, Math.min(100, percent0));
dev[“dali_light_control/brightness_0”] = percent0;
if (percent0 > 0) brightnessPercent_0 = percent0;
dev[“dali_light_control/power_0”] = (dali0 > 0);
// Канал 1
var dali1 = safeFloat(dev["dali_logic_lite_ps_x1_1/Device 1 Brightness"], 0);
var percent1 = Math.round(dali1 * 100 / 254);
percent1 = Math.max(0, Math.min(100, percent1));
dev["dali_light_control/brightness_1"] = percent1;
if (percent1 > 0) brightnessPercent_1 = percent1;
dev["dali_light_control/power_1"] = (dali1 > 0);
// Канал 2
var dali2 = safeFloat(dev["dali_logic_lite_ps_x1_1/Device 2 Brightness"], 0);
var percent2 = Math.round(dali2 * 100 / 254);
percent2 = Math.max(0, Math.min(100, percent2));
dev["dali_light_control/brightness_2"] = percent2;
if (percent2 > 0) brightnessPercent_2 = percent2;
dev["dali_light_control/power_2"] = (dali2 > 0);
publishState();
} catch(e) {
log("Error in dali_to_virtual: " + e);
}
updating = false;
}
});
// ============================================
// ИНИЦИАЛИЗАЦИЯ
// ============================================
setTimeout(function() {
try {
var dali0 = safeFloat(dev[“dali_logic_lite_ps_x1_1/Device 0 Brightness”], 0);
var dali1 = safeFloat(dev[“dali_logic_lite_ps_x1_1/Device 1 Brightness”], 0);
var dali2 = safeFloat(dev[“dali_logic_lite_ps_x1_1/Device 2 Brightness”], 0);
dev[“dali_light_control/power_0”] = (dali0 > 0);
dev[“dali_light_control/brightness_0”] = Math.round(dali0 * 100 / 254);
dev[“dali_light_control/power_1”] = (dali1 > 0);
dev[“dali_light_control/brightness_1”] = Math.round(dali1 * 100 / 254);
dev[“dali_light_control/power_2”] = (dali2 > 0);
dev[“dali_light_control/brightness_2”] = Math.round(dali2 * 100 / 254);
publishState();
log("Init DALI: " + dali0 + ", " + dali1 + ", " + dali2);
} catch(e) {
log("Error in init: " + e);
}
}, 1000);
Проблема была в логике работы правила virtual_to_dali . При включении питания (power_0 = true ) код отправлял в DALI значение яркости, которое было в виртуальном устройстве (0), а не последнее сохраненное значение. Это приводило к тому, что свет не включался, так как DALI получал команду на яркость 0.
Было:
javascript
// При включении питания яркость = 0 var daliValue_0 = toDaliValue(dev[“dali_light_control/power_0”], brightnessPercent_0); // brightnessPercent_0 = 0, так как яркость в виртуальном устройстве = 0 // В DALI отправляется 0
Стало:
javascript
// Если питание ВКЛ, но яркость = 0 - ставим последнюю яркость if (power0 && bright0 === 0) { dev[“dali_light_control/brightness_0”] = lastBrightness[0]; bright0 = lastBrightness[0]; } // Теперь в DALI отправляется последняя сохраненная яркость (например, 100%)
Что было сделано:
- Добавлен массив
lastBrightnessдля хранения последней яркости каждого канала - Добавлена логика восстановления яркости при включении питания
- Добавлено сохранение яркости при любом изменении ползунка
- Инициализация
lastBrightnessзначениями из DALI при старте
Результат: Теперь при включении питания через виртуальное устройство свет включается с последней сохраненной яркостью (по умолчанию 100%), а не с нулевой.
Исправленное правило
// ============================================
// ВИРТУАЛЬНОЕ УСТРОЙСТВО (3 канала)
// ============================================
defineVirtualDevice(“dali_light_control”, {
title: “DALI Light Control”,
cells: {
power_0: { type: “switch”, value: false },
brightness_0: { type: “range”, value: 0, max: 100, min: 0 },
power_1: { type: “switch”, value: false },
brightness_1: { type: “range”, value: 0, max: 100, min: 0 },
power_2: { type: “switch”, value: false },
brightness_2: { type: “range”, value: 0, max: 100, min: 0 }
}
});
// ============================================
// ПЕРЕМЕННЫЕ
// ============================================
var lastBrightness = [100, 100, 100]; // запоминаем яркость для каждого канала
// ============================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
// ============================================
function getNum(val) {
var n = parseFloat(val);
return isNaN(n) ? 0 : n;
}
function getBool(val) {
return val === true || val === 1 || val === “1” || val === “true” || val === “on”;
}
// ============================================
// ОБНОВЛЕНИЕ DALI ИЗ ВИРТУАЛЬНОГО УСТРОЙСТВА
// ============================================
defineRule(“virtual_to_dali”, {
whenChanged: [
“dali_light_control/power_0”,
“dali_light_control/brightness_0”,
“dali_light_control/power_1”,
“dali_light_control/brightness_1”,
“dali_light_control/power_2”,
“dali_light_control/brightness_2”
],
then: function() {
// КАНАЛ 0
var power0 = getBool(dev[“dali_light_control/power_0”]);
var bright0 = getNum(dev[“dali_light_control/brightness_0”]);
// Если яркость изменилась и > 0 - запоминаем
if (bright0 > 0) {
lastBrightness[0] = bright0;
}
// Если питание ВКЛ, но яркость = 0 - ставим последнюю яркость
if (power0 && bright0 === 0) {
dev["dali_light_control/brightness_0"] = lastBrightness[0];
bright0 = lastBrightness[0];
}
// Отправляем в DALI
dev["dali_logic_lite_ps_x1_1/Device 0 Brightness"] = power0 ? Math.round(bright0 * 254 / 100) : 0;
// КАНАЛ 1
var power1 = getBool(dev["dali_light_control/power_1"]);
var bright1 = getNum(dev["dali_light_control/brightness_1"]);
if (bright1 > 0) {
lastBrightness[1] = bright1;
}
if (power1 && bright1 === 0) {
dev["dali_light_control/brightness_1"] = lastBrightness[1];
bright1 = lastBrightness[1];
}
dev["dali_logic_lite_ps_x1_1/Device 1 Brightness"] = power1 ? Math.round(bright1 * 254 / 100) : 0;
// КАНАЛ 2
var power2 = getBool(dev["dali_light_control/power_2"]);
var bright2 = getNum(dev["dali_light_control/brightness_2"]);
if (bright2 > 0) {
lastBrightness[2] = bright2;
}
if (power2 && bright2 === 0) {
dev["dali_light_control/brightness_2"] = lastBrightness[2];
bright2 = lastBrightness[2];
}
dev["dali_logic_lite_ps_x1_1/Device 2 Brightness"] = power2 ? Math.round(bright2 * 254 / 100) : 0;
}
});
// ============================================
// ОБНОВЛЕНИЕ ВИРТУАЛЬНОГО ИЗ DALI
// ============================================
defineRule(“dali_to_virtual”, {
whenChanged: [
“dali_logic_lite_ps_x1_1/Device 0 Brightness”,
“dali_logic_lite_ps_x1_1/Device 1 Brightness”,
“dali_logic_lite_ps_x1_1/Device 2 Brightness”
],
then: function() {
// КАНАЛ 0
var dali0 = getNum(dev[“dali_logic_lite_ps_x1_1/Device 0 Brightness”]);
var percent0 = Math.round(dali0 * 100 / 254);
dev[“dali_light_control/brightness_0”] = percent0;
dev[“dali_light_control/power_0”] = dali0 > 0;
if (percent0 > 0) lastBrightness[0] = percent0;
// КАНАЛ 1
var dali1 = getNum(dev["dali_logic_lite_ps_x1_1/Device 1 Brightness"]);
var percent1 = Math.round(dali1 * 100 / 254);
dev["dali_light_control/brightness_1"] = percent1;
dev["dali_light_control/power_1"] = dali1 > 0;
if (percent1 > 0) lastBrightness[1] = percent1;
// КАНАЛ 2
var dali2 = getNum(dev["dali_logic_lite_ps_x1_1/Device 2 Brightness"]);
var percent2 = Math.round(dali2 * 100 / 254);
dev["dali_light_control/brightness_2"] = percent2;
dev["dali_light_control/power_2"] = dali2 > 0;
if (percent2 > 0) lastBrightness[2] = percent2;
}
});
// ============================================
// ПРИНИМАЕМ КОМАНДЫ ИЗ MQTT
// ============================================
defineRule(“mqtt_in”, {
when: {
mqtt: {
“/devices/dali_light_control/controls/power_0”: “.",
“/devices/dali_light_control/controls/brightness_0”: ".”,
“/devices/dali_light_control/controls/power_1”: “.",
“/devices/dali_light_control/controls/brightness_1”: ".”,
“/devices/dali_light_control/controls/power_2”: “.",
“/devices/dali_light_control/controls/brightness_2”: ".”
}
},
then: function(msg) {
var parts = msg.topic.split(‘/’);
var name = parts[parts.length - 1];
var channel = name.split(‘‘)[1];
var type = name.split(’’)[0];
if (type === "power") {
dev["dali_light_control/power_" + channel] = getBool(msg.value);
} else {
var val = Math.min(100, Math.max(0, getNum(msg.value)));
dev["dali_light_control/brightness_" + channel] = val;
if (val > 0) lastBrightness[channel] = val;
}
}
});
// ============================================
// ОТПРАВЛЯЕМ СОСТОЯНИЕ В MQTT
// ============================================
defineRule(“publish_state”, {
whenChanged: [
“dali_light_control/power_0”,
“dali_light_control/brightness_0”,
“dali_light_control/power_1”,
“dali_light_control/brightness_1”,
“dali_light_control/power_2”,
“dali_light_control/brightness_2”
],
then: function() {
publish(“/devices/dali_light_control/controls/power_0”, String(dev[“dali_light_control/power_0”] ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_0”, String(dev[“dali_light_control/brightness_0”]), { retain: true });
publish(“/devices/dali_light_control/controls/power_1”, String(dev[“dali_light_control/power_1”] ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_1”, String(dev[“dali_light_control/brightness_1”]), { retain: true });
publish(“/devices/dali_light_control/controls/power_2”, String(dev[“dali_light_control/power_2”] ? 1 : 0), { retain: true });
publish(“/devices/dali_light_control/controls/brightness_2”, String(dev[“dali_light_control/brightness_2”]), { retain: true });
}
});
// ============================================
// ИНИЦИАЛИЗАЦИЯ
// ============================================
setTimeout(function() {
var d0 = getNum(dev[“dali_logic_lite_ps_x1_1/Device 0 Brightness”]);
var d1 = getNum(dev[“dali_logic_lite_ps_x1_1/Device 1 Brightness”]);
var d2 = getNum(dev[“dali_logic_lite_ps_x1_1/Device 2 Brightness”]);
var p0 = Math.round(d0 * 100 / 254);
var p1 = Math.round(d1 * 100 / 254);
var p2 = Math.round(d2 * 100 / 254);
dev["dali_light_control/power_0"] = d0 > 0;
dev["dali_light_control/brightness_0"] = p0;
if (p0 > 0) lastBrightness[0] = p0;
dev["dali_light_control/power_1"] = d1 > 0;
dev["dali_light_control/brightness_1"] = p1;
if (p1 > 0) lastBrightness[1] = p1;
dev["dali_light_control/power_2"] = d2 > 0;
dev["dali_light_control/brightness_2"] = p2;
if (p2 > 0) lastBrightness[2] = p2;
log("DALI init: " + d0 + ", " + d1 + ", " + d2);
}, 1000);
Добрый день!
Благодарю за информацию!
Ошибка не связана с обновлением ПО.