KNX demo-stand: различия между версиями
Ian (обсуждение | вклад) |
|||
(не показано 17 промежуточных версий 4 участников) | |||
Строка 1: | Строка 1: | ||
{{DISPLAYTITLE: Демонстрационный стенд KNX }} | |||
==Описание == | |||
{{note|info|Информация в статье устарела}} | |||
Выставочный демо-стенд WB-KNX. Создан, как пример использования контроллера Wiren Board с модулем KNX. Стенд оснащен оборудованием с разными шинами и протоколами, объединяя их в одну систему через контроллер WB6. | Выставочный демо-стенд WB-KNX. Создан, как пример использования контроллера Wiren Board с модулем KNX. Стенд оснащен оборудованием с разными шинами и протоколами, объединяя их в одну систему через контроллер WB6. | ||
<gallery mode="packed" heights="200px"> | |||
Image: Knx_stand_2.png | Демо-cтенд WB-KNX | |||
Image: Knx_stand_1.png | Демо-cтенд WB-KNX | |||
Image: Knx_stand_3.png | Диммер HDL M/D06.1, Релейный модуль GIRA 2152 00/I01 | |||
Image: Knx_stand_4.png | Панельки HDL P03.2-A и MPT14.1 | |||
Image: Knx_stand_5.png | Контроллер WB6, релейный модуль WBIO-DO-R10A-8, модули входов WBIO-DI-DR-8 и WBIO-DI-HVD-8, датчик температуры DS18B20 | |||
Image: Knx_stand_6.png | Modbus устройства WB-MDM2, WB-MR3LV/S, WB-MRGB | |||
Image: Knx_stand_7.png | Блок питания KNX Berker | |||
</gallery> | |||
== Состав == | == Состав == | ||
Строка 63: | Строка 66: | ||
Основная идея стенда - показать взаимодействие между устройствами с разными протоколами. И то, что контроллер [[Wiren Board 6]] может расширить уже существующую автоматизацию на KNX другими более дешевыми устройствами. | Основная идея стенда - показать взаимодействие между устройствами с разными протоколами. И то, что контроллер [[Wiren Board 6]] может расширить уже существующую автоматизацию на KNX другими более дешевыми устройствами. | ||
Либо наоборот, если Вам захотелось добавить в проект красивую KNX панельку, при этом остальное оборудование работает по modbus. | Либо наоборот, если Вам захотелось добавить в проект красивую KNX панельку, при этом остальное оборудование работает по modbus. Далее подробно рассмотрим настройку стенда и написание правил. | ||
[[File:Knx_stand_sch.png|450px|thumb|center|Схема Демо-Стенда WB-KNX]] | [[File:Knx_stand_sch.png|450px|thumb|center|Схема Демо-Стенда WB-KNX]] | ||
== Настройка контроллера == | == Настройка контроллера == | ||
Для начала настроим модули Wirenboard. Для этого в web-интерфейсе переходим в раздел | Для начала настроим модули Wirenboard. Для этого в web-интерфейсе переходим в раздел '''Configs → Hardware Modules Configuration''' И выбираем установленные модули. В нашем случаеː | ||
Internal slot 1 - Вставлен [[KNX Module for WB6 (WBE2-I-KNX)]], выбираем "WBE2-I-KNX: KNX/EIB TP-UART" | Internal slot 1 - Вставлен [[KNX Module for WB6 (WBE2-I-KNX)]], выбираем "WBE2-I-KNX: KNX/EIB TP-UART" | ||
Строка 81: | Строка 84: | ||
[[File:Hwconf-knx1.PNG|250px|thumb|center|Настройка модуля WBE2-I-KNX]] | [[File:Hwconf-knx1.PNG|250px|thumb|center|Настройка модуля WBE2-I-KNX]] | ||
Настраиваем modbus устройства. Для этого в web-интерфейсе переходим в раздел | Настраиваем modbus устройства. Для этого в web-интерфейсе переходим в раздел '''Configs → Serial Device Driver Configuration''' и задаем нужные параметры. Как это сделать можно посмотреть в документации к устройствам, здесь подробно об этом писать не буду. | ||
[[File:Mqtt-serial-knxStand.PNG|250px|thumb|center|Настройка modbus устройств]] | [[File:Mqtt-serial-knxStand.PNG|250px|thumb|center|Настройка modbus устройств]] | ||
Следующим шагом будет установка и настройка программ для работы с KNX. А именноː '''[[Knxd]]''' - Для взаимодействия с шиной KNX, '''[[KnxTool]]''' - для отладки, '''[[WB-KNXD-CONFIG]]''' - для удобной настройки KNXD через веб-интерфейс контроллера, '''[[MQTT_KNX]]''' - для взаимодействия движка правил | Следующим шагом будет установка и настройка программ для работы с KNX. А именноː '''[[Knxd]]''' - Для взаимодействия с шиной KNX, '''[[KnxTool]]''' - для отладки, '''[[WB-KNXD-CONFIG]]''' - для удобной настройки KNXD через веб-интерфейс контроллера, '''[[MQTT_KNX]]''' - для взаимодействия движка правил '''([[Движок правил wb-rules]])''' c '''[[Knxd]]'''. Для установки всех программ разом введите команду в консольː | ||
<pre>$ apt-get update && apt-get install knxd knxd-tools wb-knxd-config wb-mqtt-knx</pre> | <pre>$ apt-get update && apt-get install knxd knxd-tools wb-knxd-config wb-mqtt-knx</pre> | ||
После установки программ в web-интерфейсе переходим в раздел | После установки программ в web-интерфейсе переходим в раздел '''Configs → KNXD Configuration''' для настройки KNXD. | ||
"'''Driver (-b, --layer2)'''" - В этом поле нужно указать драйвер и путь к устройству. В нашем случае указываем '''ncn5120:/dev/ttyKNX1''' | "'''Driver (-b, --layer2)'''" - В этом поле нужно указать драйвер и путь к устройству. В нашем случае указываем '''ncn5120:/dev/ttyKNX1''' | ||
Строка 110: | Строка 113: | ||
Остальные настройки на данный момент нам не интересны. Сохраняем изменения нажав кнопку "Save". На этом закончим настройку контроллера и перейдем к настройке KNX устройств через ETS5. | Остальные настройки на данный момент нам не интересны. Сохраняем изменения нажав кнопку "Save". На этом закончим настройку контроллера и перейдем к настройке KNX устройств через ETS5. | ||
== Настройка KNX устройств == | == Настройка KNX устройств через ETS5 == | ||
Для настройки KNX устройств нам понадобится программа ETS5. Для наших целей сойдет бесплатная демо-версия (до 5 устройств на проект). Скачать можно с '''[https://my.knx.org/en/shop/software сайта knx.org]'''. Устанавливаем, запускаем. | |||
Далее нужно выбрать интерфейс. Заходим во вкладку '''Системная Шина → Соединения → Интерфейсы'''. Здесь во вкладке "Показать интерфейсы" отображаются автоматически найденные по бродкаст адресу интерфейсы. Если интерфейсы не определились автоматически, то во вкладке "Сконфигурированные интерфейсы" можно нажать кнопку '''"добавить" → "IP Tunneling"''' и справа ввести IP адрес контроллера с запущенным KNXD, указав порт 3671 и нажать кнопку "выбрать". | |||
После этого возвращаемся в вкладку "Обзор" и создаем новый проект (или импортируем уже готовый, если имеется). В новом проекте создаем комнату и называем на пример "KNX стенд". Нажимаем на комнату '''→ Добавить → Устройство'''. Откроется вкладка каталога устройств. В нашем случае необходимых устройств в каталоге нет. Их нужно импортировать из специального файла, который распространяет производитель (HDL). Необходимые файлы можно найти '''[https://drive.google.com/drive/folders/1zZXMKCmfKpn-SUYXp7OrmiLE_DN772VW на гугл диске компании HDL]'''. Находим нужные файлы и импортируем их в ETS5, после чего добавляем нужные устройства в комнату '''KNX стенд'''. | |||
Далее настраиваем каждое устройствоː задаем индивидуальный адрес, включаем необходимые функции и присваиваем им групповые адреса. Если необходимо связываем устройства групповыми адресами между собой. Полный процесс настройки описывать так же нет смысла. Для каждого устройства он индивидуальный. Ниже я оставлю ссылку на проект и все используемые для этого проекта файлы. | |||
Как только все устройства настроены, адреса заданы - выбираем в верхнем меню '''→ Ввод в эксплуатацию → Загрузка → Полная загрузка →''' Следуя указаниям на экране нажимайте на кнопки "Режима загрузки" на устройствах для загрузки программ. | |||
<gallery mode="packed" heights="200px"> | |||
File:Knx stand ets1.PNG|Добавляем интерфейс в ручную. | |||
File:Knx stand ets2.PNG|Конфигурирование устройств. | |||
File:Knx stand ets3.PNG|Загрузка программ в устройства. | |||
</gallery> | |||
После того как проект успешно загружен можно переходить к написанию правил на контроллере WB6. | |||
Скачать готовый ETS5 проект стенда можно [https://wirenboard.com/wiki/images/d/d1/Wb-knx.zip по ссылке] | |||
== Правила wb-rules == | |||
Зайдите в веб интерфейс контроллера и создайте новое правило во вкладке "Scripts". | |||
=== Вспомогательное правило для KNX === | |||
Вспомогательное правило помогает избежать лишних действий при работе с KNX. При получении посылки в топик "knx/data" данные парсятся и раскладываются по топикам. Для каждого группового адреса создается отдельный контрол. При изменении этого контрола данные так же отправляются обратно в топик "knx/data" для отправки на шину KNX. В объекте knx_vdev_obj мы можем явно указать заранее известные групповые адреса и задать им необходимый тип. | |||
<syntaxhighlight lang="ecmascript"> | |||
(function() { | |||
var knx_vdev_obj = { | |||
title: "KNX Group Addresses", | |||
cells: { | |||
"1-1-1": { | |||
type: "value", | |||
value: "0" | |||
}, | |||
"1-1-2": { | |||
type: "switch", | |||
value: false | |||
}, | |||
"1-1-3": { | |||
type: "range", | |||
max: 255, | |||
value: 0, | |||
knx_type: "wide" | |||
}, | |||
"1-1-6": { | |||
type: "switch", | |||
value: false | |||
}, | |||
"1-1-7": { | |||
type: "value", | |||
value: "0" | |||
}, | |||
"1-1-8": { | |||
type: "value", | |||
value: "0" | |||
}, | |||
"1-1-9": { | |||
type: "value", | |||
value: "0" | |||
}, | |||
"1-1-10": { | |||
type: "switch", | |||
value: false | |||
}, | |||
"1-1-11": { | |||
type: "switch", | |||
value: false | |||
}, | |||
"1-1-12": { | |||
type: "value", | |||
value: "0" | |||
}, | |||
"1-1-13": { | |||
type: "value", | |||
value: 0, | |||
knx_type: "wide" | |||
} | |||
} | |||
}; | |||
var vdev_when_changed = []; | |||
var vdev_devid = "knx_group_addrs"; | |||
for (var control_id in knx_vdev_obj.cells) { | |||
if (knx_vdev_obj.cells.hasOwnProperty(control_id)) { | |||
vdev_when_changed.push("knx_group_addrs/" + control_id); | |||
} | |||
} | |||
defineVirtualDevice(vdev_devid, knx_vdev_obj); | |||
defineRule("knx_vdev_feedback", { | |||
whenChanged: vdev_when_changed, | |||
then: function(newValue, devName, cellName) { | |||
var group_address = cellName.split("-").join("/"); | |||
var value = +newValue; | |||
var write_str = ""; | |||
if (knx_vdev_obj.cells[cellName].knx_type == "wide") { | |||
while (value > 0) { | |||
var rem = value % 256; | |||
value = Math.floor(value / 256); | |||
write_str = rem + " " + write_str; | |||
} | |||
write_str = "0 " + write_str; | |||
} else { | |||
write_str = "" + value; | |||
} | |||
if (write_str) { | |||
dev["knx/data"] = "g:{} GroupValueWrite {}".format(group_address, write_str); | |||
} | |||
} | |||
}); | |||
defineRule("knx_vdev_incoming", { | |||
whenChanged: "knx/data", | |||
then: function(newValue, devName, cellName) { | |||
var arr = newValue.split(/\s/); | |||
var sourceAddr = arr[0].split(/i\:|\,/); | |||
var groupAddr = arr[1].split(/g\:|\,/); | |||
var arr1 = newValue.split(/GroupValueWrite/); | |||
var value = arr1[1]; | |||
if ((sourceAddr[1] == "0/0/0") || (sourceAddr[1] == "1/1/255")) { // skip local echo | |||
return; | |||
} | |||
dev[vdev_devid][groupAddr[1].split("/").join("-")] = !!parseInt(value, 16); | |||
} | |||
}); | |||
})() | |||
function knxConvertToFloat16(value) { | |||
var sign = 0; | |||
var exp = 0; | |||
if (value < 0) { | |||
sign = 1; | |||
} | |||
var mant = Math.floor(value * 100); | |||
while ((mant < -2048) || (mant > 2047)) { | |||
mant = mant >> 1; | |||
exp += 1 | |||
} | |||
var data = (sign << 15) | (exp << 11) | (mant & 0x07ff); | |||
return data; | |||
}; | |||
</syntaxhighlight> | |||
=== Основное правило === | |||
Если предыдущее правило универсальное и может быть использовано почти в каждом проекте, то это правило написано специально для нашего стенда. Здесь уже нет сложных преобразований, мы просто следим за необходимыми нам топиками и реагируем на их изменения. | |||
<syntaxhighlight lang="ecmascript"> | |||
(function() { | |||
var channel_pairs = [ | |||
["knx_group_addrs/1-1-10", "wb-gpio/EXT1_R3A1"], // По нажатию на KNX кнопку, к которой привязан групповой адрес 1/1/10 включать или выключать индикатор 2 | |||
["knx_group_addrs/1-1-11", "wb-mr3_139/K1"] | |||
]; | |||
function makePairRules(chan1, chan2) { | |||
defineRule("channel_pair_follow_" + chan1 + "_" + chan2, { | |||
whenChanged: chan1, | |||
then: function(newValue, devName, cellName) { | |||
dev[chan2] = newValue; | |||
} | |||
}); | |||
}; | |||
for (var i = 0; i < channel_pairs.length; ++i) { | |||
var chan1 = channel_pairs[i][0]; | |||
var chan2 = channel_pairs[i][1]; | |||
makePairRules(chan1, chan2); | |||
makePairRules(chan2, chan1); | |||
} | |||
defineRule("hdl_panel_set_temp", { | |||
whenChanged: "wb-w1/28-041643cee6ff", | |||
then: function(newValue, devName, cellName) { | |||
dev["knx_group_addrs/1-1-13"] = knxConvertToFloat16(newValue + 2); // Передаем на KNX панельку температуру с датчика DS18B20 | |||
} | |||
}); | |||
defineRule("dimmer_chan1", { | |||
whenChanged: "knx_group_addrs/1-1-7", | |||
then: function(newValue, devName, cellName) { | |||
if (newValue == 11) { | |||
dev["wb-mdm2_1/Channel 1"] = Math.min(dev["wb-mdm2_1/Channel 1"] + 10, 100); // Если зажать KNX кнопку - увеличиваем яркость modbus диммера на 10 % единиц. | |||
} else if (newValue == 3) { | |||
dev["wb-mdm2_1/Channel 1"] = Math.max(dev["wb-mdm2_1/Channel 1"] - 10, 0); | |||
} | |||
} | |||
}); | |||
defineRule("hdl_dimmer_chan1_on_off", { | |||
whenChanged: "wb-gpio/EXT2_DR1", | |||
then: function(newValue, devName, cellName) { | |||
if (newValue) { | |||
dev["knx_group_addrs/1-1-2"] = !dev["knx_group_addrs/1-1-2"]; // По нажатию на обычный выключатель звонкового типа переключаем KNX диммер | |||
} | |||
} | |||
}); | |||
defineRule("dimmer_chan1_on_off", { | |||
whenChanged: "wb-gpio/EXT2_DR2", | |||
then: function(newValue, devName, cellName) { | |||
if (newValue) { | |||
dev["knx_group_addrs/1-1-6"] = !dev["knx_group_addrs/1-1-6"] | |||
} | |||
} | |||
}); | |||
defineRule("dimmer_chan1_on_off_knx", { | |||
whenChanged: "knx_group_addrs/1-1-6", | |||
then: function(newValue, devName, cellName) { | |||
if (newValue) { | |||
dev["wb-mdm2_1/Channel 1"] = 70; | |||
} else { | |||
dev["wb-mdm2_1/Channel 1"] = 0; | |||
} | |||
} | |||
}); | |||
})(); | |||
function knxConvertToFloat16(value) { | |||
var sign = 0; | |||
var exp = 0; | |||
if (value < 0) { | |||
sign = 1; | |||
} | |||
var mant = Math.floor(value * 100); | |||
while ((mant < -2048) || (mant > 2047)) { | |||
mant = mant >> 1; | |||
exp += 1 | |||
} | |||
var data = (sign << 15) | (exp << 11) | (mant & 0x07ff); | |||
return data; | |||
}; | |||
</syntaxhighlight> |
Текущая версия на 16:20, 12 апреля 2022
Описание
Информация в статье устарела Выставочный демо-стенд WB-KNX. Создан, как пример использования контроллера Wiren Board с модулем KNX. Стенд оснащен оборудованием с разными шинами и протоколами, объединяя их в одну систему через контроллер WB6.
Состав
Оборудование KNX
1) Панелька HDL MPT14 Controller (HDL-M/MPT14.1 v1.0-1)
2) Панелька HDL Panel 3 Rocker Controller (HDL-M/P03.2-A v.HDL-V1.2-6)
3) Диммер HDL M/D06.1
4) Релейный модуль GIRA 2152 00/I01
5) Блок питания KNX Berker
Оборудование WB
2) KNX Module for WB6 (WBE2-I-KNX) (вставлен в разъем MOD1 контроллера WB6)
3) WBIO-DO-R10A-8 Relay Module
5) Модуль наличия 220В (WBIO-DI-HVD-8)
Modbus оборудование
Порт RS485-1 (115200 8n2)
1) WB-MRGB-D (A:21)
2) WB-MD2 230V Dimmer (A:1)
3) WB-MR3LV/S(A:139)
Другое оборудование
1) Блок питания faraday 12w/12-24v/din (2шт)
2) Датчик температуры DS18B20
3) Индикаторы 220v (2шт)
4) Лампы накаливания (2шт)
5) Выключатели звонкового типа (2шт)
6) Светодиодная лента RGB
Описание
Основная идея стенда - показать взаимодействие между устройствами с разными протоколами. И то, что контроллер Wiren Board 6 может расширить уже существующую автоматизацию на KNX другими более дешевыми устройствами. Либо наоборот, если Вам захотелось добавить в проект красивую KNX панельку, при этом остальное оборудование работает по modbus. Далее подробно рассмотрим настройку стенда и написание правил.
Настройка контроллера
Для начала настроим модули Wirenboard. Для этого в web-интерфейсе переходим в раздел Configs → Hardware Modules Configuration И выбираем установленные модули. В нашем случаеː
Internal slot 1 - Вставлен KNX Module for WB6 (WBE2-I-KNX), выбираем "WBE2-I-KNX: KNX/EIB TP-UART"
External I/O module 1 - подключен модуль WBIO-DO-R10A-8 Relay Module, выбираем "WBIO-DO-RxA-8: 8 Channel Relay I/O module"
External I/O module 2 - подключен модуль WBIO-DI-DR-8 I/O Module, выбираем "WBIO-DI-DR-8: Digital inputs (dry contact) I/O module"
External I/O module 3 - подключен Модуль наличия 220В (WBIO-DI-HVD-8), выбираем "WBIO-DI-HVD-8: High Voltage Digital Inputs I/O module"
После этого нажимаем кнопку "Save".
Настраиваем modbus устройства. Для этого в web-интерфейсе переходим в раздел Configs → Serial Device Driver Configuration и задаем нужные параметры. Как это сделать можно посмотреть в документации к устройствам, здесь подробно об этом писать не буду.
Следующим шагом будет установка и настройка программ для работы с KNX. А именноː Knxd - Для взаимодействия с шиной KNX, KnxTool - для отладки, WB-KNXD-CONFIG - для удобной настройки KNXD через веб-интерфейс контроллера, MQTT_KNX - для взаимодействия движка правил (Движок правил wb-rules) c Knxd. Для установки всех программ разом введите команду в консольː
$ apt-get update && apt-get install knxd knxd-tools wb-knxd-config wb-mqtt-knx
После установки программ в web-интерфейсе переходим в раздел Configs → KNXD Configuration для настройки KNXD.
"Driver (-b, --layer2)" - В этом поле нужно указать драйвер и путь к устройству. В нашем случае указываем ncn5120:/dev/ttyKNX1
"EIB address (-e, --eibaddr)" - задаем EIB адрес нашему контроллеру 1.1.255
"Client-addrs (-E, --client-addrs)" - указываем диапазон адресов, которые будут выдаваться EIB клиентам 1.1.5:50
"Discovery (-D, --Discovery)" - Ставим галку, что бы контроллер отвечал на запросы поиска.
"Tunnelling (-T, --Tunnelling)" - Ставим галку
"Routing (-R, --Routing)" - Ставим галку
"Server (-S, --Server)" - Тоже ставим галку, что бы включить EIBnet/IP multicast сервер на контроллере
"Custom name of the server" - Произвольное имя сервера. Впишем WirenboardKNX
"Server address" - Оставим именно этот адрес, что бы сервер автоматически определялся в ETS5ː 224.0.23.12:3671
Остальные настройки на данный момент нам не интересны. Сохраняем изменения нажав кнопку "Save". На этом закончим настройку контроллера и перейдем к настройке KNX устройств через ETS5.
Настройка KNX устройств через ETS5
Для настройки KNX устройств нам понадобится программа ETS5. Для наших целей сойдет бесплатная демо-версия (до 5 устройств на проект). Скачать можно с сайта knx.org. Устанавливаем, запускаем.
Далее нужно выбрать интерфейс. Заходим во вкладку Системная Шина → Соединения → Интерфейсы. Здесь во вкладке "Показать интерфейсы" отображаются автоматически найденные по бродкаст адресу интерфейсы. Если интерфейсы не определились автоматически, то во вкладке "Сконфигурированные интерфейсы" можно нажать кнопку "добавить" → "IP Tunneling" и справа ввести IP адрес контроллера с запущенным KNXD, указав порт 3671 и нажать кнопку "выбрать".
После этого возвращаемся в вкладку "Обзор" и создаем новый проект (или импортируем уже готовый, если имеется). В новом проекте создаем комнату и называем на пример "KNX стенд". Нажимаем на комнату → Добавить → Устройство. Откроется вкладка каталога устройств. В нашем случае необходимых устройств в каталоге нет. Их нужно импортировать из специального файла, который распространяет производитель (HDL). Необходимые файлы можно найти на гугл диске компании HDL. Находим нужные файлы и импортируем их в ETS5, после чего добавляем нужные устройства в комнату KNX стенд.
Далее настраиваем каждое устройствоː задаем индивидуальный адрес, включаем необходимые функции и присваиваем им групповые адреса. Если необходимо связываем устройства групповыми адресами между собой. Полный процесс настройки описывать так же нет смысла. Для каждого устройства он индивидуальный. Ниже я оставлю ссылку на проект и все используемые для этого проекта файлы.
Как только все устройства настроены, адреса заданы - выбираем в верхнем меню → Ввод в эксплуатацию → Загрузка → Полная загрузка → Следуя указаниям на экране нажимайте на кнопки "Режима загрузки" на устройствах для загрузки программ.
После того как проект успешно загружен можно переходить к написанию правил на контроллере WB6.
Скачать готовый ETS5 проект стенда можно по ссылке
Правила wb-rules
Зайдите в веб интерфейс контроллера и создайте новое правило во вкладке "Scripts".
Вспомогательное правило для KNX
Вспомогательное правило помогает избежать лишних действий при работе с KNX. При получении посылки в топик "knx/data" данные парсятся и раскладываются по топикам. Для каждого группового адреса создается отдельный контрол. При изменении этого контрола данные так же отправляются обратно в топик "knx/data" для отправки на шину KNX. В объекте knx_vdev_obj мы можем явно указать заранее известные групповые адреса и задать им необходимый тип.
(function() {
var knx_vdev_obj = {
title: "KNX Group Addresses",
cells: {
"1-1-1": {
type: "value",
value: "0"
},
"1-1-2": {
type: "switch",
value: false
},
"1-1-3": {
type: "range",
max: 255,
value: 0,
knx_type: "wide"
},
"1-1-6": {
type: "switch",
value: false
},
"1-1-7": {
type: "value",
value: "0"
},
"1-1-8": {
type: "value",
value: "0"
},
"1-1-9": {
type: "value",
value: "0"
},
"1-1-10": {
type: "switch",
value: false
},
"1-1-11": {
type: "switch",
value: false
},
"1-1-12": {
type: "value",
value: "0"
},
"1-1-13": {
type: "value",
value: 0,
knx_type: "wide"
}
}
};
var vdev_when_changed = [];
var vdev_devid = "knx_group_addrs";
for (var control_id in knx_vdev_obj.cells) {
if (knx_vdev_obj.cells.hasOwnProperty(control_id)) {
vdev_when_changed.push("knx_group_addrs/" + control_id);
}
}
defineVirtualDevice(vdev_devid, knx_vdev_obj);
defineRule("knx_vdev_feedback", {
whenChanged: vdev_when_changed,
then: function(newValue, devName, cellName) {
var group_address = cellName.split("-").join("/");
var value = +newValue;
var write_str = "";
if (knx_vdev_obj.cells[cellName].knx_type == "wide") {
while (value > 0) {
var rem = value % 256;
value = Math.floor(value / 256);
write_str = rem + " " + write_str;
}
write_str = "0 " + write_str;
} else {
write_str = "" + value;
}
if (write_str) {
dev["knx/data"] = "g:{} GroupValueWrite {}".format(group_address, write_str);
}
}
});
defineRule("knx_vdev_incoming", {
whenChanged: "knx/data",
then: function(newValue, devName, cellName) {
var arr = newValue.split(/\s/);
var sourceAddr = arr[0].split(/i\:|\,/);
var groupAddr = arr[1].split(/g\:|\,/);
var arr1 = newValue.split(/GroupValueWrite/);
var value = arr1[1];
if ((sourceAddr[1] == "0/0/0") || (sourceAddr[1] == "1/1/255")) { // skip local echo
return;
}
dev[vdev_devid][groupAddr[1].split("/").join("-")] = !!parseInt(value, 16);
}
});
})()
function knxConvertToFloat16(value) {
var sign = 0;
var exp = 0;
if (value < 0) {
sign = 1;
}
var mant = Math.floor(value * 100);
while ((mant < -2048) || (mant > 2047)) {
mant = mant >> 1;
exp += 1
}
var data = (sign << 15) | (exp << 11) | (mant & 0x07ff);
return data;
};
Основное правило
Если предыдущее правило универсальное и может быть использовано почти в каждом проекте, то это правило написано специально для нашего стенда. Здесь уже нет сложных преобразований, мы просто следим за необходимыми нам топиками и реагируем на их изменения.
(function() {
var channel_pairs = [
["knx_group_addrs/1-1-10", "wb-gpio/EXT1_R3A1"], // По нажатию на KNX кнопку, к которой привязан групповой адрес 1/1/10 включать или выключать индикатор 2
["knx_group_addrs/1-1-11", "wb-mr3_139/K1"]
];
function makePairRules(chan1, chan2) {
defineRule("channel_pair_follow_" + chan1 + "_" + chan2, {
whenChanged: chan1,
then: function(newValue, devName, cellName) {
dev[chan2] = newValue;
}
});
};
for (var i = 0; i < channel_pairs.length; ++i) {
var chan1 = channel_pairs[i][0];
var chan2 = channel_pairs[i][1];
makePairRules(chan1, chan2);
makePairRules(chan2, chan1);
}
defineRule("hdl_panel_set_temp", {
whenChanged: "wb-w1/28-041643cee6ff",
then: function(newValue, devName, cellName) {
dev["knx_group_addrs/1-1-13"] = knxConvertToFloat16(newValue + 2); // Передаем на KNX панельку температуру с датчика DS18B20
}
});
defineRule("dimmer_chan1", {
whenChanged: "knx_group_addrs/1-1-7",
then: function(newValue, devName, cellName) {
if (newValue == 11) {
dev["wb-mdm2_1/Channel 1"] = Math.min(dev["wb-mdm2_1/Channel 1"] + 10, 100); // Если зажать KNX кнопку - увеличиваем яркость modbus диммера на 10 % единиц.
} else if (newValue == 3) {
dev["wb-mdm2_1/Channel 1"] = Math.max(dev["wb-mdm2_1/Channel 1"] - 10, 0);
}
}
});
defineRule("hdl_dimmer_chan1_on_off", {
whenChanged: "wb-gpio/EXT2_DR1",
then: function(newValue, devName, cellName) {
if (newValue) {
dev["knx_group_addrs/1-1-2"] = !dev["knx_group_addrs/1-1-2"]; // По нажатию на обычный выключатель звонкового типа переключаем KNX диммер
}
}
});
defineRule("dimmer_chan1_on_off", {
whenChanged: "wb-gpio/EXT2_DR2",
then: function(newValue, devName, cellName) {
if (newValue) {
dev["knx_group_addrs/1-1-6"] = !dev["knx_group_addrs/1-1-6"]
}
}
});
defineRule("dimmer_chan1_on_off_knx", {
whenChanged: "knx_group_addrs/1-1-6",
then: function(newValue, devName, cellName) {
if (newValue) {
dev["wb-mdm2_1/Channel 1"] = 70;
} else {
dev["wb-mdm2_1/Channel 1"] = 0;
}
}
});
})();
function knxConvertToFloat16(value) {
var sign = 0;
var exp = 0;
if (value < 0) {
sign = 1;
}
var mant = Math.floor(value * 100);
while ((mant < -2048) || (mant > 2047)) {
mant = mant >> 1;
exp += 1
}
var data = (sign << 15) | (exp << 11) | (mant & 0x07ff);
return data;
};