Контроллеры Wago в "Умном доме"
Контроллеры Wago в "Умном доме"
Эта тема является ответвлением темы Ali Элементы "умного дома" на Beckhoff . Посвящена она будет контроллерам Wago, а именно Wago 750-881. Все примеры честно содраны у Ali (за что ему отдельное СПАСИБО!). Решил открыть ее, т.к. несмотря на то, что Beckhoff и Wago близнеци-братья, а отличия все-таки есть.
На отличия или неосвещенные в теме Ali возможности контроллера и будет основной упор в моем повествовании.
На отличия или неосвещенные в теме Ali возможности контроллера и будет основной упор в моем повествовании.
Re: Контроллеры Wago в "Умном доме"
Начать, я думаю, стоит с настроек подключения. Все настройки находятся в меню «Онлайн -> Параметры связи…» в появившемся окне нажимаем «Gateway», далее надо указать localhost - драйвер будет запущен на том же компьютере, где и CoDeSys.
Далее жмем «New», выбираем S3 Tcp/ip driver. Указываем IP адрес контроллера, и порт 2455.
Важно заметить, что любые изменения параметров в полях ввода надо заканчивать нажатием клавиши Enter, иначе значение поменяется, а применено не будет – потратил на выяснение этой фичи целый день.
Все это выяснилось потом, а с начала я воспользовался китайским переходником USB-COM с выходными уровнями 5 вольт, купленным на eBay за целый доллар. Магазинный переходник без переделки использовать нельзя, вернее можно, но потребуется микросхема-преобразователь MAX232 или аналогичная.
Распайка разъема WAGO сверху вниз:
1 - TxD (передача, выход) - подключить к выводу T1IN MAX232 или RX китайского переходника.
2 - RxD (прием, вход) - подключить к выводу R1OUT MAX232 или TX китайского переходника.
3 - Vcc (питание +5V) - отсюда взять питание для MAX232 - для китайского переходника не используется.
4 - GND (общий)
При таком способе подключения все делается как для сети, только выбирать нужно S3 Serial RS232 driver. Все настройки по умолчанию, за исключением номера COM порта.
Далее жмем «New», выбираем S3 Tcp/ip driver. Указываем IP адрес контроллера, и порт 2455.
Важно заметить, что любые изменения параметров в полях ввода надо заканчивать нажатием клавиши Enter, иначе значение поменяется, а применено не будет – потратил на выяснение этой фичи целый день.
Все это выяснилось потом, а с начала я воспользовался китайским переходником USB-COM с выходными уровнями 5 вольт, купленным на eBay за целый доллар. Магазинный переходник без переделки использовать нельзя, вернее можно, но потребуется микросхема-преобразователь MAX232 или аналогичная.
Распайка разъема WAGO сверху вниз:
1 - TxD (передача, выход) - подключить к выводу T1IN MAX232 или RX китайского переходника.
2 - RxD (прием, вход) - подключить к выводу R1OUT MAX232 или TX китайского переходника.
3 - Vcc (питание +5V) - отсюда взять питание для MAX232 - для китайского переходника не используется.
4 - GND (общий)
При таком способе подключения все делается как для сети, только выбирать нужно S3 Serial RS232 driver. Все настройки по умолчанию, за исключением номера COM порта.
Re: Контроллеры Wago в "Умном доме"
У контроллера Wago есть интересная возможность получения значений и записи переменных контроллера с помощью HTTP запросов к нему.
Получение значений переменных может выглядеть это так:
_http://admin:wago@192.168.100.181/READPI?ADR=QW2&FORMAT=%d - Прочитать состояние 16 выходов QX2.0 – QX2.15.
_http://admin:wago@192.168.100.181/READPI?ADR=QX2.0&FORMAT=%d - Прочитать состояние выхода QX2.0.
_http://admin:wago@192.168.100.181/READPI?ADR=IX0.0&FORMAT=%d - Прочитать состояние входа IX0.0.
Аналогично можно прочитать любую переменную.
Формат запроса очень прост – логин, пароль, адрес контроллера. Далее, через слеш, следует команда чтения «READPI» и параметры адрес переменной и формат вывода.
Формат вывода может быть «%d» - десятичный или «%x» - шестнадцатиричный.
Аналогично можно записать новое значение переменным MX и MW, использовав вместо команды чтения «READPI», команду «WRITEPI».
_http://admin:wago@192.168.100.181/WRITEPI?ADR1=MW1600&VALUE1=31&FORMAT1=%d - Записать десятичное значение 31 в переменную MW1600.
Стоит сразу сказать, что на GET запросы такого вида контроллер ругается, но выполняет, для записи надо использовать POST запросы.
Также, для общения с контроллером, можно использовать SSI скрипты расположенные на виртуальном диске контроллера. Вот пример SSI скрипта, найденный на каком то польском форуме. Этот скрипт отображает состояние выходов и с помощью переменной MW1600, позволяет переключать их состояние.
Правда, я его немного доработал под свою задачу.
Осталось научить контроллер обращаться с девайсами типа «мегадевайса» или «1Wire по Ethernet» и писать в базу данных, расположенную на сервере, но об этом позже, и так уже много букв.
Получение значений переменных может выглядеть это так:
_http://admin:wago@192.168.100.181/READPI?ADR=QW2&FORMAT=%d - Прочитать состояние 16 выходов QX2.0 – QX2.15.
_http://admin:wago@192.168.100.181/READPI?ADR=QX2.0&FORMAT=%d - Прочитать состояние выхода QX2.0.
_http://admin:wago@192.168.100.181/READPI?ADR=IX0.0&FORMAT=%d - Прочитать состояние входа IX0.0.
Аналогично можно прочитать любую переменную.
Формат запроса очень прост – логин, пароль, адрес контроллера. Далее, через слеш, следует команда чтения «READPI» и параметры адрес переменной и формат вывода.
Формат вывода может быть «%d» - десятичный или «%x» - шестнадцатиричный.
Аналогично можно записать новое значение переменным MX и MW, использовав вместо команды чтения «READPI», команду «WRITEPI».
_http://admin:wago@192.168.100.181/WRITEPI?ADR1=MW1600&VALUE1=31&FORMAT1=%d - Записать десятичное значение 31 в переменную MW1600.
Стоит сразу сказать, что на GET запросы такого вида контроллер ругается, но выполняет, для записи надо использовать POST запросы.
Также, для общения с контроллером, можно использовать SSI скрипты расположенные на виртуальном диске контроллера. Вот пример SSI скрипта, найденный на каком то польском форуме. Этот скрипт отображает состояние выходов и с помощью переменной MW1600, позволяет переключать их состояние.
Код: Выделить всё
<html>
<head>
<script language="JavaScript">
<!--
function Start()
{
var Tags = new Array (<!--#READPI ADR=MX1600.0&FORMAT=%d-->,
<!--#READPI ADR=MX1600.1&FORMAT=%d-->,
<!--#READPI ADR=MX1600.2&FORMAT=%d-->,
<!--#READPI ADR=MX1600.3&FORMAT=%d-->,
<!--#READPI ADR=MX1600.4&FORMAT=%d-->,
<!--#READPI ADR=MX1600.5&FORMAT=%d-->);
var Outs = new Array (<!--#READPI ADR=QX2.0&FORMAT=%d-->,
<!--#READPI ADR=QX2.1&FORMAT=%d-->,
<!--#READPI ADR=QX2.2&FORMAT=%d-->,
<!--#READPI ADR=QX2.3&FORMAT=%d-->,
<!--#READPI ADR=QX2.4&FORMAT=%d-->,
<!--#READPI ADR=QX2.5&FORMAT=%d-->);
for (var i = 0; i < Tags.length; i++)
{
if (Tags[i]>0)
{
document.forms["DataTable"].elements["ADR1"].value='MX1600.'+i;
document.forms["DataTable"].submit();
}
}
for (var i = 1; i < Outs.length+1; i++)
{
if (Outs[i-1]==1)
{
document.forms["Control"].elements["Button"+i].value="OFF";
}
}
}
function ChangeAndPost(TagNo)
{
document.forms["DataTable"].elements["ADR1"].value="MX1600."+TagNo;
document.forms["DataTable"].elements["VALUE1"].value="1";
document.forms["DataTable"].submit();
}
//-->
</script>
<style type="text/css">
p {font-family:"Arial", Helvetica, sans-serif;}
</style>
</head>
<body onload="Start();">
<FORM name="Control">
<TABLE align="left" border="0">
<TR>
<TD align="left" width='100'><p>Ванна</p></TD>
<TD align="center" width='30'><p><!--#READPI ADR=QX2.0&FORMAT=%d--></p></TD>
<TD align="center" width='60'><input type="button" name="Button1" value="ON" onclick="ChangeAndPost('0')"></td>
</TR>
<TR>
<TD align="left"><p>Туалет</p></TD>
<TD align="center"><p><!--#READPI ADR=QX2.1&FORMAT=%d--></p></TD>
<TD align="center"><input type="button" name="Button2" value="ON" onclick="ChangeAndPost('1')"></td>
</TR>
<TR>
<TD align="left"><p>Предбанник</p></TD>
<TD align="center"><p><!--#READPI ADR=QX2.2&FORMAT=%d--></p></TD>
<TD align="center"><input type="button" name="Button3" value="ON" onclick="ChangeAndPost('2')"></td>
</TR>
<TR>
<TD align="left"><p>Комната</p></TD>
<TD align="center"><p><!--#READPI ADR=QX2.3&FORMAT=%d--></p></TD>
<TD align="center"><input type="button" name="Button4" value="ON" onclick="ChangeAndPost('3')"></td>
</TR>
<TR>
<TD align="left"><p>Спальня</p></TD>
<TD align="center"><p><!--#READPI ADR=QX2.4&FORMAT=%d--></p></TD>
<TD align="center"><input type="button" name="Button5" value="ON" onclick="ChangeAndPost('4')"></td>
</TR>
<TR>
<TD align="left"><p>Прихожая</p></TD>
<TD align="center"><p><!--#READPI ADR=QX2.5&FORMAT=%d--></p></TD>
<TD align="center"><input type="button" name="Button6" value="ON" onclick="ChangeAndPost('5')"></td>
</TR>
</table>
</FORM>
<!-- Форма для запись в контроллер -->
<FORM action="/WRITEPI" method="POST" name="DataTable">
<input type="hidden" name="ADR1" value="MB0">
<input type="hidden" name="VALUE1" value="0" >
<input type="hidden" name="FORMAT1" value="%d">
</FORM>
</body>
</html>
Осталось научить контроллер обращаться с девайсами типа «мегадевайса» или «1Wire по Ethernet» и писать в базу данных, расположенную на сервере, но об этом позже, и так уже много букв.
- Вложения
-
- control.rar
- (946 байт) 501 скачивание
Re: Контроллеры Wago в "Умном доме"
Хорошее дело делаете
Ещё не плохо будет указать какие из модулей на этих контролёрах взаимозаменяемые. Ну и прочую информацию. Потому как очень мало данных по этой теме, а желающих попробовать применить возможности ПЛК для дома всё больше.
Так что спасибо вам за труды.
Ещё не плохо будет указать какие из модулей на этих контролёрах взаимозаменяемые. Ну и прочую информацию. Потому как очень мало данных по этой теме, а желающих попробовать применить возможности ПЛК для дома всё больше.
Так что спасибо вам за труды.
Re: Контроллеры Wago в "Умном доме"
Pagan, спасибо на добром слове.
Про взаимозаменяемость модулей у меня информации пока нет.
И так, продолжим...
Не давал мне покоя способ общения с готовыми девайсами типа мегадевайса, вроде библиотеки для отправки GET запросов есть (HTTP_GET входит в состав библиотеки WagoLibHttp_02.lib), а что дальше? Как обрабатывать ответ девайса?
Решение нашлось после нескольких неудачных попыток получить значения влажности и температуры с датчика DHT-22, подключенного вот к этому девайсу - Управление вентиляцией по Ethernet.
Вот код функционального блока, решающего эту задачу. Объявление переменных:
Основной код блока:
В работе блока используется функция FLOAT_TO_REAL библиотеки OSCAT файл библиотеки - oscat_basic_333.lib
Вот так выглядит вызов этого блока на языке LD: Сообщение обновлено 25.11.2014. В код модуля добавлен расчет точки росы.
Про взаимозаменяемость модулей у меня информации пока нет.
И так, продолжим...
Не давал мне покоя способ общения с готовыми девайсами типа мегадевайса, вроде библиотеки для отправки GET запросов есть (HTTP_GET входит в состав библиотеки WagoLibHttp_02.lib), а что дальше? Как обрабатывать ответ девайса?
Решение нашлось после нескольких неудачных попыток получить значения влажности и температуры с датчика DHT-22, подключенного вот к этому девайсу - Управление вентиляцией по Ethernet.
Вот код функционального блока, решающего эту задачу. Объявление переменных:
Код: Выделить всё
FUNCTION_BLOCK FB_VENT_DHT
VAR_INPUT
ServerName: STRING;
Sensor: UINT;
END_VAR
VAR_OUTPUT
Error: BOOL := FALSE;
Humidity: REAL;
Temperature: REAL;
DewPoint: REAL;
END_VAR
VAR
Http_1: HTTP_GET;
Content: ARRAY [0..MAX_RECEIVE_TCP_CLIENT] OF BYTE;
Length: UINT;
Url: ARRAY [0..1] OF STRING := '/sec/?dht=1','/sec/?dht=2';
pt:POINTER TO BYTE;
tmp: STRING(5) := '';
count: UINT;
f_T_Rh: REAL;
END_VAR
VAR_IN_OUT
Send: BOOL;
END_VAR
Код: Выделить всё
Error := FALSE;
IF (Sensor >=1 AND Sensor <= 2) THEN
Http_1(
sServerName:= ServerName,
pabUrlData:= ADR(Url[Sensor-1]),
uiUrlLength:= LEN(Url[Sensor-1]),
tTimeOut:= T#1S,
xSend:= Send,
diError=> ,
sStatus=> ,
abContentData=> Content,
uiContentLength=> Length);
IF Http_1.diError > 0 THEN Error := TRUE; ELSE Error := FALSE; END_IF
IF (Content[0]<16#3C AND Length > 0) THEN
count := 0;
pt:=ADR(tmp);
WHILE Content[count]<>16#3B DO (* ?????????? ?????? ?? ??????? ";" - ????????? *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
Humidity := FLOAT_TO_REAL(tmp);
count:=count+1; (* ???????????? ?????? ";" *)
tmp := '';
pt:=ADR(tmp);
WHILE (Content[count]<>0 AND count<Length) DO (* ?????????? ?????? ?? ????? - ??????????? *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
Temperature := FLOAT_TO_REAL(tmp);
(*Формула обладает погрешностью ±0.4 °С в диапазоне температуры воздуха Т от 0°С до 60°С,
температуры точки росы Тр от 0°С до 50°С, относительной влажности Rh от 1% до 100%.*)
f_T_Rh := ((17.27 * Temperature) / (237.7 + Temperature)) + LN(Humidity / 100);
DewPoint := (237.7 * f_T_Rh) / (17.27 - f_T_Rh) ;
ELSE
Error := TRUE;
Humidity := 0;
Temperature := 0;
END_IF
ELSE
Error := TRUE;
END_IF
Вот так выглядит вызов этого блока на языке LD: Сообщение обновлено 25.11.2014. В код модуля добавлен расчет точки росы.
Re: Контроллеры Wago в "Умном доме"
Вот, случайно наткнулся на ссылку: _http://forum.skunksworks.net/Forum10/HTML/001125.htmlPagan писал(а):Ещё не плохо будет указать какие из модулей на этих контролёрах взаимозаменяемые. Ну и прочую информацию. Потому как очень мало данных по этой теме, а желающих попробовать применить возможности ПЛК для дома всё больше.
Похоже проблем с использованием дискретных модулей нет, для аналоговых возможно потребуется бубен.
Re: Контроллеры Wago в "Умном доме"
Долго думал, как лучше организовать управление выходами самопальных девайсов, решил, что удобнее всего эмитировать работу с обычным выходом контроллера. В результате написал функциональный блок...
И основной код:
Этот блок по фронтам входного сигнала отправляет команды удаленному устройству на включение и выключение выхода.
В своей работе использует вот эту функцию:
Почему то в стандартных библиотеках не нашлось функции преобразования байта в строку с десятичной цифрой. Перевод в двоичное и шестнадцатеричное число есть, а в десятичное нет. Пришлось написать самому...
Код: Выделить всё
FUNCTION_BLOCK FB_VENT_OUTL
VAR_INPUT
ServerName: STRING;
Out: BYTE;
In: BOOL;
END_VAR
VAR_OUTPUT
Error: BOOL := FALSE;
END_VAR
VAR
HttpGet: HTTP_GET;
Length: UINT;
Url: STRING(24);
stmp: STRING(24);
Val: STRING(1);
MEM: BOOL;
Send: BOOL;
END_VAR
VAR CONSTANT
Url1: STRING := '/sec/?out=';
Url2: STRING := '&val=';
END_VAR
Код: Выделить всё
Error := FALSE;
IF In AND NOT MEM THEN (*Передний фронт*)
Val:='1';
Send:=TRUE;
END_IF
IF NOT In AND MEM THEN (*Задний фронт*)
Val:='0';
Send:=TRUE;
END_IF
IF Send THEN
Url := CONCAT (Url1,BYTE_TO_STRD(Out));
stmp := CONCAT (Url,Url2);
Url := CONCAT (stmp,Val);
HttpGet(
sServerName:= ServerName,
pabUrlData:= ADR(Url),
uiUrlLength:= LEN(Url),
tTimeOut:= T#1S,
xSend:= Send,
uiContentLength=> Length);
END_IF
IF ((Length >0 AND Length <>2) OR HttpGet.diError <>0) THEN Error := TRUE; END_IF
MEM := In;
В своей работе использует вот эту функцию:
Код: Выделить всё
FUNCTION BYTE_TO_STRD : STRING(4)
VAR_INPUT
IN:BYTE;
END_VAR
VAR
pt: POINTER TO BYTE;
tmp: BYTE;
str: STRING(4);
fd: BOOL:=FALSE;
END_VAR
Код: Выделить всё
pt := ADR(str);
tmp:=0;
WHILE IN >= 100 DO (* *)
tmp:=tmp+1;
IN :=IN-100;
END_WHILE
IF tmp > 0 THEN
tmp:= tmp+48;
pt^ := tmp;
pt:=pt+1;
fd:=TRUE;
END_IF
tmp:=0;
WHILE IN >= 10 DO (* *)
tmp:=tmp+1;
IN :=IN-10;
END_WHILE
IF(( tmp > 0) OR fd) THEN
tmp:= tmp+48;
pt^ := tmp;
pt:=pt+1;
END_IF
tmp:=0;
WHILE IN >= 1 DO (* *)
tmp:=tmp+1;
IN :=IN-1;
END_WHILE
tmp:= tmp+48;
pt^ := tmp;
pt:=pt+1;
pt^ := 0;
BYTE_TO_STRD :=str;
Re: Контроллеры Wago в "Умном доме"
Немного отошел от написания логики - решил сделать резервную страничку для управления освещением которая храниться в самом контроллере. Думаю этот пример написания WEB приложений для контроллеров Wago будет интересен многим.
Сразу хочу оговориться, что скрипты на странице не работают в IE. Отладка проводилась в FireFox 17. Позже планирую это исправить, желающим исправить (обойти) баги IE самостоятельно, рекомендую посмотреть вот эту страницу XMLHTTPRequest: описание, применение, частые проблемы. В разделе "Частые проблемы" все подробно описано.
Есть еще одна проблема с IE - смена стилей. Она не описана в этой статье...
Анекдот на правах руководства к действию:
IE, это такая программа, которая служит для того, чтобы скачать себе браузер.
Вот что у меня получилось:
Добавлено. 22:40
Решилась проблема с IE, теперь все работает. Проблем с утечкой памяти не заметил, возможно она появляется при условиях, которые в моих скриптах не используются.
На очереди PID регулятор для управления положением заслонки вентиляции.
Сразу хочу оговориться, что скрипты на странице не работают в IE. Отладка проводилась в FireFox 17. Позже планирую это исправить, желающим исправить (обойти) баги IE самостоятельно, рекомендую посмотреть вот эту страницу XMLHTTPRequest: описание, применение, частые проблемы. В разделе "Частые проблемы" все подробно описано.
Есть еще одна проблема с IE - смена стилей. Она не описана в этой статье...
Анекдот на правах руководства к действию:
IE, это такая программа, которая служит для того, чтобы скачать себе браузер.
Вот что у меня получилось:
Добавлено. 22:40
Решилась проблема с IE, теперь все работает. Проблем с утечкой памяти не заметил, возможно она появляется при условиях, которые в моих скриптах не используются.
На очереди PID регулятор для управления положением заслонки вентиляции.
Re: Контроллеры Wago в "Умном доме"
Просмотрел статью про еще раз, в коде осталась только одна проблема:
Добавлено.
Отредактировал пост выше, перезалил архив.
Похоже в данном случае, описываемая проблема не проявляется.
Нужно ли ее "решать", да еще таким кривым способом, не знаю - те, кто пользуются ХР, преследуют определенные цели и почти наверняка не используют IE, а в Win7 и так должно все работать (не тестировал, у меня ХР ).Утечки памяти
В Internet Explorer объект XmlHttpRequest принадлежит миру DOM/COM, а Javascript-функция - миру Javascript. Присваивание xmlhttp.onreadystatechange = function() { ... } задает неявную круговую связь: xmlhttp ссылается на функцию через onreadystatechange, а функция, через свою область видимости - видит (ссылается на) xmlhttp.
Невозможность обнаружить и оборвать такую связь во многих (до IE 6,7 редакции июня 2007?) версиях Internet Explorer приводит к тому, что XmlHttpRequest вместе с ответом сервера, функция-обработчик и всё замыкание прочно оседают в памяти до перезагрузки браузера.
Чтобы этого избежать, ряд фреймворков (YUI, dojo...) вообще не ставят onreadystatechange, а вместо этого через setTimeout проверяют его readyState каждые 10 миллисекунд. Это разрывает круговую связку xmlhttp <-> onreadystatechange, и утечка памяти не грозит даже в самых глючных браузерах.
Добавлено.
Отредактировал пост выше, перезалил архив.
Похоже в данном случае, описываемая проблема не проявляется.
Re: Контроллеры Wago в "Умном доме"
У меня контроллер 750-841, отличий от 881 много?
Кстати с одним контроллером вышла проблема, он не определялся через tcp/ip никак, сброс настроек, мониторинг трафика, ничего не помогало. Пришлось покупать сервисный кабель кабель.
Кстати с одним контроллером вышла проблема, он не определялся через tcp/ip никак, сброс настроек, мониторинг трафика, ничего не помогало. Пришлось покупать сервисный кабель кабель.
Re: Контроллеры Wago в "Умном доме"
Нет. Я пользуюсь русским даташитом на 841 контроллер. 881 это более производительная замена 841 контроллера, но для домашнего применения это не критично.radon писал(а):У меня контроллер 750-841, отличий от 881 много?
ИМХО Отличия только в способе настройки, у 881 все делается через WEB интерфейс.
PS Сильно отличается контроллер 750-842...
Во втором посту данной темы распайка сервисного разъема. Проверено - все работает как с родным кабелем, по началу пользовался именно таким подключением.radon писал(а):Пришлось покупать сервисный кабель.
На всякий случай, мой текущий проект, вдруг кому будет интересно взглянуть...
Re: Контроллеры Wago в "Умном доме"
Что то со временем туго стало, не удается осуществить задуманное.
В качестве памятки:
SysLibRtc.lib - доступ к часам RTC контроллеров 750-841, 750-881 и может еще каким то. Входит в состав CodeSys по умолчанию.
Scheduler_03.lib - планировщик задач, позволяет планировать задачи по времени и дням недели. Доступна на гитхабе.
Building_HVAC_01.lib - набор библиотек на все случаи жизни для управления инженерными системами здания, может будет кому то интересно. Доступна на гитхабе.
В качестве памятки:
SysLibRtc.lib - доступ к часам RTC контроллеров 750-841, 750-881 и может еще каким то. Входит в состав CodeSys по умолчанию.
Scheduler_03.lib - планировщик задач, позволяет планировать задачи по времени и дням недели. Доступна на гитхабе.
Building_HVAC_01.lib - набор библиотек на все случаи жизни для управления инженерными системами здания, может будет кому то интересно. Доступна на гитхабе.
Re: Контроллеры Wago в "Умном доме"
Давно не писал...
За это время доработал WEB - теперь выводятся аналоговые значения, обновляются AJAX'сом и изрядно "причесал" прошивку - разбил ее на отдельные модули, так удобнее и понятней. Надеюсь кому то пригодится в качестве примера и сэкономит время - пришлось долго возится с аяксом.
PS Жаль времени на все не хватает.
За это время доработал WEB - теперь выводятся аналоговые значения, обновляются AJAX'сом и изрядно "причесал" прошивку - разбил ее на отдельные модули, так удобнее и понятней. Надеюсь кому то пригодится в качестве примера и сэкономит время - пришлось долго возится с аяксом.
PS Жаль времени на все не хватает.
- Вложения
-
- Screen.JPG (34.67 КБ) 18317 просмотров
Re: Контроллеры Wago в "Умном доме"
Думал тема умерла - никто не пишет, ан нет! Наработки просматривается и скачиваются...
Выкладываю последние архивы своей системы. Многое доработано, переписано и усовершенствовано. В процессе своих мытарств столкнулся с одним неприятным ограничением контроллера - одновременно можно открыть не более 3 HTTP соединений. В доке, конечно, это указано, но я думал это относится только к открытию страничек WEB интерфейса, что легко обходится настройкой прокси на апаче сервера. Как оказалось в это число входят и исходящие соединения с контроллера к другим девайсам.
Надо переходить на Modbus TCP (поддерживается 15 соединений)...
Из за этого пришлось полностью менять идеологию управления устройствами. Вот так теперь выглядит FB для управления заслонками вентиляции: Долго помучился со стилями на странице управления освещением, теперь (по мотивам статьи Андрея Рисуем план дома для управления освещением) она выглядит вот так: Для удобства сделал страничку, где можно наблюдать за изменением состояния всех IO, доступных контроллеру. Ну и наконец то разобрался с изменением настроек каких то блоков контроллера из WEB'а. На вторую и третью колонки внимание не обращайте, это оставлено, чтобы видеть границы колонок. Значения в них не обновляются. Вся вкусность в первой колонке... Из проблем WEB'а.
Скорее всего в IE отображение будет корявым, у меня ХР, поэтому нормально проверить интерфейс не получается, Слишком много "нового" в нем используется. Буду рад, если кто то проверит у себя на Win7 (можно просто открыть странички на компьютере не загружая их в контроллер) и напишет результат, а еще лучше, устранит увиденные баги. С версткой у меня явно проблемы...
Все отлаживалось в FireFox 30.
Выкладываю последние архивы своей системы. Многое доработано, переписано и усовершенствовано. В процессе своих мытарств столкнулся с одним неприятным ограничением контроллера - одновременно можно открыть не более 3 HTTP соединений. В доке, конечно, это указано, но я думал это относится только к открытию страничек WEB интерфейса, что легко обходится настройкой прокси на апаче сервера. Как оказалось в это число входят и исходящие соединения с контроллера к другим девайсам.
Надо переходить на Modbus TCP (поддерживается 15 соединений)...
Из за этого пришлось полностью менять идеологию управления устройствами. Вот так теперь выглядит FB для управления заслонками вентиляции: Долго помучился со стилями на странице управления освещением, теперь (по мотивам статьи Андрея Рисуем план дома для управления освещением) она выглядит вот так: Для удобства сделал страничку, где можно наблюдать за изменением состояния всех IO, доступных контроллеру. Ну и наконец то разобрался с изменением настроек каких то блоков контроллера из WEB'а. На вторую и третью колонки внимание не обращайте, это оставлено, чтобы видеть границы колонок. Значения в них не обновляются. Вся вкусность в первой колонке... Из проблем WEB'а.
Скорее всего в IE отображение будет корявым, у меня ХР, поэтому нормально проверить интерфейс не получается, Слишком много "нового" в нем используется. Буду рад, если кто то проверит у себя на Win7 (можно просто открыть странички на компьютере не загружая их в контроллер) и напишет результат, а еще лучше, устранит увиденные баги. С версткой у меня явно проблемы...
Все отлаживалось в FireFox 30.
- Вложения
-
- 2015.07.20_WWW.rar
- (36.9 КБ) 302 скачивания
-
- 2015.07.20_750-881.rar
- (1.02 МБ) 311 скачиваний
Re: Контроллеры Wago в "Умном доме"
Переписал FB_VENT.
Теперь, благодаря простенькому конвейеру-битовому автомату, этот FB не теряет входные сигналы при их одновременном появлении и сам распределяет запросы к модулю во времени. Добавил комментарии.
Объявление переменных:
Текст самого блока:
Кроме этого добавил простенький алгоритм для определения скорости роста влажности и включения вентилятора.
25.07.2015 Изменен текст блока - теперь есть проверка перед отправкой команды, что выполнение предыдущей команды закончено.
Теперь, благодаря простенькому конвейеру-битовому автомату, этот FB не теряет входные сигналы при их одновременном появлении и сам распределяет запросы к модулю во времени. Добавил комментарии.
Объявление переменных:
Код: Выделить всё
FUNCTION_BLOCK FB_VENT
VAR_INPUT
ServerName: STRING;
Send_Period: WORD := 300;
Out1: BOOL := FALSE;
Out2: BOOL := FALSE;
Out3: BOOL := FALSE;
Out4: BOOL := FALSE;
Out5: BOOL := FALSE;
DU1: WORD := 50;
Delta1: WORD := 1;
DU2: WORD := 50;
Delta2: WORD := 1;
DHT_1: BOOL := FALSE;
DHT_2: BOOL := FALSE;
Hum_Limit: REAL := 5;
Mes_Period: WORD := 10;
DewPoint_Off: REAL := 16;
END_VAR
VAR_OUTPUT
Error: WORD := 0;
Humidity1: REAL := 0;
Temperature1: REAL := 0;
DewPoint1: REAL := 0;
Humidity2: REAL := 0;
Temperature2: REAL := 0;
DewPoint2: REAL := 0;
Exhaust_Fan: BOOL := FALSE;
END_VAR
VAR
HttpGet: HTTP_GET;
Content: ARRAY [0..MAX_RECEIVE_TCP_CLIENT] OF BYTE;
Length: UINT;
count: UINT;
pt:POINTER TO BYTE;
Url: STRING(24);
Val: STRING(5);
MEM1: BOOL:=FALSE;
MEM2: BOOL:=FALSE;
MEM3: BOOL:=FALSE;
MEM4: BOOL:=FALSE;
MEM5: BOOL:=FALSE;
DHT_MEM1: BOOL:=FALSE;
DHT_MEM2: BOOL:=FALSE;
Send: BOOL;
DUtmp1: INT;
DUtmp2: INT;
tmp: STRING(8) := '';
f_T_Rh: REAL;
T_Cicle: BLINK;
R_Cicle: R_TRIG;
T_Conv: BLINK;
R_Conv: R_TRIG;
Hum_tmp1: REAL;
DWOR_TO_TIME: BOOL;
Conv: ARRAY [0..13] OF BOOL := 14(FALSE);
Conv_Index: WORD:=0;
Index: WORD := 0;
END_VAR
VAR CONSTANT
sUrl: ARRAY [0..13] OF STRING := '/sec/?out=1&val=1',
'/sec/?out=1&val=0',
'/sec/?out=2&val=1',
'/sec/?out=2&val=0',
'/sec/?out=3&val=1',
'/sec/?out=3&val=0',
'/sec/?out=4&val=1',
'/sec/?out=4&val=0',
'/sec/?out=5&val=1',
'/sec/?out=5&val=0',
'/sec/?srv=1&du=',
'/sec/?srv=2&du=',
'/sec/?dht=1',
'/sec/?dht=2';
END_VAR
Код: Выделить всё
(***********************************************************************************************************************)
(** Анализ вохдных сигналов блока и постановка задач на конвейер **)
(***********************************************************************************************************************)
(* DHT #1 *)
IF DHT_1 AND NOT DHT_MEM1 THEN Conv[12] := TRUE; END_IF (*Передний фронт*)
DHT_MEM1 := DHT_1;
(* DHT #2 *)
IF DHT_2 AND NOT DHT_MEM2 THEN Conv[13] := TRUE; END_IF (*Передний фронт*)
DHT_MEM2 := DHT_2;
(* Servo #1 *)
IF (DU1 >=0 AND DU1 <= 100 AND Delta1>0) THEN
IF ((DU1>=(DUtmp1+Delta1)) OR (DU1<=(DUtmp1-Delta1))) THEN DUtmp1:=DU1; Conv[10] := TRUE; END_IF
ELSE Error.10 := TRUE; END_IF
(* Servo #2 *)
IF (DU2 >=0 AND DU2 <= 100 AND Delta2>0) THEN
IF ((DU2>=(DUtmp2+Delta2)) OR (DU2<=(DUtmp2-Delta2))) THEN DUtmp2:=DU2; Conv[11] := TRUE; END_IF
ELSE Error.11 := TRUE; END_IF
(* Out 1 *)
IF Out1 AND NOT MEM1 THEN Conv[0] := TRUE; END_IF (*Передний фронт*)
IF NOT Out1 AND MEM1 THEN Conv[1] := TRUE; END_IF (*Задний фронт*)
MEM1 := Out1;
(* Out 2 *)
IF Out2 AND NOT MEM2 THEN Conv[2] := TRUE; END_IF (*Передний фронт*)
IF NOT Out2 AND MEM2 THEN Conv[3] := TRUE; END_IF (*Задний фронт*)
MEM2 := Out2;
(* Out 3 *)
IF Out3 AND NOT MEM3 THEN Conv[4] := TRUE; END_IF (*Передний фронт*)
IF NOT Out3 AND MEM3 THEN Conv[5] := TRUE; END_IF (*Задний фронт*)
MEM3 := Out3;
(* Out 4 *)
IF Out4 AND NOT MEM4 THEN Conv[6] := TRUE; END_IF (*Передний фронт*)
IF NOT Out4 AND MEM4 THEN Conv[7] := TRUE; END_IF (*Задний фронт*)
MEM4 := Out4;
(* Out 5 *)
IF Out5 AND NOT MEM5 THEN Conv[8] := TRUE; END_IF (*Передний фронт*)
IF NOT Out5 AND MEM5 THEN Conv[9] := TRUE; END_IF (*Задний фронт*)
MEM5 := Out5;
(***********************************************************************************************************************)
(** Конвейер отсылки команд модулю **)
(** Необходим для исключения потери событий и распределения запросов к модулю во времени **)
(***********************************************************************************************************************)
T_Conv(ENABLE:= TRUE, TIMELOW:= WORD_TO_TIME(Send_Period-1), TIMEHIGH:= T#1ms );
R_Conv(CLK:= T_Conv.OUT );
IF (Send = FALSE) THEN (*Предыдущее соединение звершено или закрыто по таймауту*)
IF R_Conv.Q THEN
IF (Conv[Conv_Index] = TRUE) THEN
Url := CONCAT (sUrl[Conv_Index],'');
(* Для этих индексов добавляем значение DU, которое было на момент постановки задачи *)
IF Conv_Index = 10 THEN Url := CONCAT (sUrl[10],INT_TO_STRING(DUtmp1)); END_IF
IF Conv_Index = 11 THEN Url := CONCAT (sUrl[11],INT_TO_STRING(DUtmp2)); END_IF
Send:=TRUE;
Conv[Conv_Index] := FALSE;
Index := Conv_Index;
END_IF
(* Просматриваем конвейер до следующей задачи или, если задач нет, до конца очереди*)
WHILE (Conv[Conv_Index] = FALSE AND Conv_Index <= 13) DO Conv_Index := Conv_Index+1; END_WHILE
IF (Conv_Index > 13) THEN Conv_Index:=0; END_IF
END_IF
END_IF
(***********************************************************************************************************************)
(** Отсылка команды модулю, прием ответа и анализ ошибок **)
(***********************************************************************************************************************)
IF Send THEN
HttpGet(
sServerName:= ServerName,
pabUrlData:= ADR(Url),
uiUrlLength:= LEN(Url),
tTimeOut:= T#10s, (*По умолчанию T#30s*)
xSend:= Send,
abContentData=> Content,
uiContentLength=> Length);
CASE Index OF
0,1: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.0 := TRUE; ELSE Error.0 := FALSE;END_IF
2,3: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.1 := TRUE; ELSE Error.1 := FALSE;END_IF
4,5: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.2 := TRUE; ELSE Error.2 := FALSE;END_IF
6,7: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.3 := TRUE; ELSE Error.3 := FALSE;END_IF
8,9: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.4 := TRUE; ELSE Error.4 := FALSE;END_IF
10: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.10 := TRUE; ELSE Error.10 := FALSE;END_IF
11: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.11 := TRUE; ELSE Error.11 := FALSE;END_IF
12: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.12 := TRUE; ELSE Error.12 := FALSE;END_IF
13: IF (HttpGet.diError <> 0 OR Length = 0) THEN Error.13 := TRUE; ELSE Error.13 := FALSE;END_IF
END_CASE
END_IF
(***********************************************************************************************************************)
(** Разбор ответа модуля и генерация ошибки при отсутствии датчика DHT **)
(***********************************************************************************************************************)
(* DHT #1 *)
IF (Index=12 AND Error.12=FALSE) THEN
IF (Content[0]<16#3C AND Length > 0) THEN
count := 0;
pt:=ADR(tmp);
WHILE Content[count]<>16#3B DO (* Перебираем массив до символа ";" - Влажность *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
pt^ := 0;
Humidity1 := FLOAT_TO_REAL(tmp);
count:=count+1; (* Проскакиваем символ ";" *)
tmp := '';
pt:=ADR(tmp);
WHILE (Content[count]<>0 AND count<Length) DO (* Перебираем массив до конца - Температура *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
pt^ := 0;
Temperature1 := FLOAT_TO_REAL(tmp);
(*Формула обладает погрешностью ±0.4 °С в диапазоне температуры воздуха Т от 0°С до 60°С,
температуры точки росы Тр от 0°С до 50°С, относительной влажности Rh от 1% до 100%.*)
f_T_Rh := ((17.27 * Temperature1) / (237.7 + Temperature1)) + LN(Humidity1 / 100);
DewPoint1 := (237.7 * f_T_Rh) / (17.27 - f_T_Rh) ;
ELSE
IF Content[0]<>0 THEN Error.12 := TRUE; END_IF
(*Humidity1 := 0;
Temperature1 := 0;*)
END_IF
END_IF
(* DHT #2 *)
IF (Index=13 AND Error.13=FALSE) THEN
IF (Content[0]<16#3C AND Length > 0) THEN
count := 0;
pt:=ADR(tmp);
WHILE Content[count]<>16#3B DO (* Перебираем массив до символа ";" - Влажность *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
pt^ := 0;
Humidity2 := FLOAT_TO_REAL(tmp);
count:=count+1; (* Проскакиваем символ ";" *)
tmp := '';
pt:=ADR(tmp);
WHILE (Content[count]<>0 AND count<Length) DO (* Перебираем массив до конца - Температура *)
pt^ := Content[count];
count:=count+1;
pt:=pt+1;
END_WHILE
pt^ := 0;
Temperature2 := FLOAT_TO_REAL(tmp);
(*Формула обладает погрешностью ±0.4 °С в диапазоне температуры воздуха Т от 0°С до 60°С,
температуры точки росы Тр от 0°С до 50°С, относительной влажности Rh от 1% до 100%.*)
f_T_Rh := ((17.27 * Temperature2) / (237.7 + Temperature2)) + LN(Humidity2 / 100);
DewPoint2 := (237.7 * f_T_Rh) / (17.27 - f_T_Rh) ;
ELSE
IF Content[0]<>0 THEN Error.13 := TRUE; END_IF
(*Humidity2 := 0;
Temperature2 := 0;*)
END_IF
END_IF
(***********************************************************************************************************************)
(**Включение вентилятора, при быстром росте влажности. Выключение при установленой точке росы. **)
(***********************************************************************************************************************)
T_Cicle(ENABLE:= TRUE, TIMELOW:= DWORD_TO_TIME(WORD_TO_DWORD(Mes_Period)*1000), TIMEHIGH:= T#1ms );
R_Cicle(CLK:= T_Cicle.OUT);
IF R_Cicle.Q THEN
IF (Humidity1>=(Hum_tmp1+ Hum_Limit)) THEN
Hum_tmp1:=Humidity1;
Exhaust_Fan := TRUE;
END_IF
IF (DewPoint1<= DewPoint_Off) THEN
Hum_tmp1:=Humidity1;
Exhaust_Fan := FALSE;
END_IF
END_IF
25.07.2015 Изменен текст блока - теперь есть проверка перед отправкой команды, что выполнение предыдущей команды закончено.
Re: Контроллеры Wago в "Умном доме"
Обнаружился баг при работе с Modbus, если слейв выключен долгое время (сутки) - контроллер "зависает", после включения слейва все начинает работать. Удалось решить проблему заменой FB из библиотеки ModbusEthernet_04.lib на такую же из WagoLibModbus_IP_01.lib.
У библиотеки WagoLibModbus_IP_01.lib в описании написано "A modbus master for the Wago IPC and 750-841 based on the SysLibSocket library.", т.е. контроллеры 750-841 и 750-881 имеют какую то особенность при работе с сетью и надо стараться использовать библиотеки предназначенные для них.
Кроме того, оказалось, что блок из WagoLibModbus_IP_01.lib немного удобнее в плане диагностики ошибок.
PS Сейчас контроллер остался без слейва примерно на неделю - получится хорошее тестирование. По результатам отпишу в этом посте.
23.08.2015
Прошел почти месяц. Контроллер так и работает без слейва, каких либо проблем в работе замечено не было, теперь с уверенностью можно сказать, что для контролеров 750-841, 750-881 для работы с Modbus TCP надо использовать библиотеку WagoLibModbus_IP_01.lib.
Жаль что не все в жизни складывается как запланировал...
У библиотеки WagoLibModbus_IP_01.lib в описании написано "A modbus master for the Wago IPC and 750-841 based on the SysLibSocket library.", т.е. контроллеры 750-841 и 750-881 имеют какую то особенность при работе с сетью и надо стараться использовать библиотеки предназначенные для них.
Кроме того, оказалось, что блок из WagoLibModbus_IP_01.lib немного удобнее в плане диагностики ошибок.
PS Сейчас контроллер остался без слейва примерно на неделю - получится хорошее тестирование. По результатам отпишу в этом посте.
23.08.2015
Прошел почти месяц. Контроллер так и работает без слейва, каких либо проблем в работе замечено не было, теперь с уверенностью можно сказать, что для контролеров 750-841, 750-881 для работы с Modbus TCP надо использовать библиотеку WagoLibModbus_IP_01.lib.
Жаль что не все в жизни складывается как запланировал...
Re: Контроллеры Wago в "Умном доме"
Столкнулся с той же проблемой, что описана вот здесь: viewtopic.php?p=21523#p21523
Решение простое, надо присваивать символьные имена выходам модулей и в программе пользоваться ими, а не адресами. После добавления модулей, адреса меняются, а символьные имена остаются. На прикрепленном скриншоте видно где это можно сделать для контроллера Wago.MerryKaze писал(а):Есть ли способ при добавлении модуля сразу скопом изменить привязку переменных к дискретным входам и выходам?
- Вложения
-
- 123.JPG (296.6 КБ) 11953 просмотра
Re: Контроллеры Wago в "Умном доме"
По просьбе в соседней ветке viewtopic.php?p=21780#p21780 , выкладываю последний архив своего проекта:
Полный архив PLC слишком большой, кому надо давайте свою почту в ЛС - вышлю.
Изменения, относительно прошлого выложенного проекта, касаются в основном интерфейса - немного добавлено, исправлены некоторые ошибки. Посмотреть его возможно в офф-лайн режиме, распаковав архив и открыв файл Heating.ssi Firefox'ом или любым другим браузером (естественно кроме IE )
Изменения, относительно прошлого выложенного проекта, касаются в основном интерфейса - немного добавлено, исправлены некоторые ошибки. Посмотреть его возможно в офф-лайн режиме, распаковав архив и открыв файл Heating.ssi Firefox'ом или любым другим браузером (естественно кроме IE )
Re: Контроллеры Wago в "Умном доме"
Приветствую ТНК! Правильно ли я понимаю, что для опроса датчиков по l2C у тебя (можно на ты?) получилось подружить ваго и мегу?
А в каком сценарии не хватило 3х http запросов?
"Надо переходить на Modbus TCP (поддерживается 15 соединений)"
под мегу есть не стандартная прошивка с поддержкой modbus?
С уважением
А в каком сценарии не хватило 3х http запросов?
"Надо переходить на Modbus TCP (поддерживается 15 соединений)"
под мегу есть не стандартная прошивка с поддержкой modbus?
С уважением
Re: Контроллеры Wago в "Умном доме"
Если точнее, то подружил я не конкретно мегу, а свои девайсы с аналогичным API. Проблем с мегой тоже не будет.nkh писал(а):Правильно ли я понимаю, что для опроса датчиков по l2C у тебя (можно на ты?) получилось подружить ваго и мегу?
Здесь речь, скорее, не о сценариях, а о подходе к написанию программы для ваго. Опрос ВСЕХ устройств должен вестись последовательным перебором с закрытием соединения по его окончании.nkh писал(а):А в каком сценарии не хватило 3х http запросов?
В настоящий момент мой ваго общается с двумя термостатами (тема "1-Wire по Ethernet") и управляет вентиляцией. Плюс к этому на компе всегда открыт веб-интерфейс. Так что главное знать о ограничениях и не использовать возможности устройства на 100%. В любой момент времени, я использую не более 2-х соединений из 3 возможных.
Где-то на форуме встречал реализацию модбас на том же стеке, что и мега. Тему не вспомню, но человеку нужен был модбас, а веб ненужен, он реализовал свои хотелки и выложил их на форуме с подробным описанием. Повторить (переделать прошивку) его подвиг проблем не составит - дорожка проторена.nkh писал(а):"Надо переходить на Modbus TCP (поддерживается 15 соединений)"
под мегу есть не стандартная прошивка с поддержкой modbus?