
В последнее время тематика умного дома набирает все большую популярность, появляются все новые и новые статьи, отзывы, обсуждения, и практически на любой вопрос можно сходу найти несколько мнений и ответов. Но во всем этом мире информации по-прежнему остается одна белая область, а именно логика работы. Мы не побоялись и решили представить на суд общественности наши заготовки по этому вопросу.
Для начала пару слов об объекте, который предстоит оснастить системами автоматизации. Это небольшой многоквартирный дом, каждая квартира которого оснащается независимыми системами кондиционирования, вентиляции, отопления и теплого пола.
В качестве основных требований заказчик отметил: единый интерфейс для управления всеми системами умного дома, ограниченный бюджет и минимальное количество дополнительной проводки. После небольшого исследования рынка систем автоматизации мы остановились на решении от Fibaro, так как основные преимущества этого решения практически идеально повторяют наши условия.
В этой статье мы опишем процесс создания подобия HVAC системы для квартиры на базе протокола Z-Wave. Надеемся получить кучу замечаний от сообщества, чтобы довести наше решение до съедобного состояния. Если ожидаемый результат будет достигнут, то мы с удовольствием продолжим этот цикл другими публикациями, в которых будем делиться своим опытом использования Z-Wave устройств.
Итак, опишем исходные данные и условия функционирования нашей системы.
В первую очередь мы задались вопросом, что будет управлять всеми системами. В качестве головного устройства мы остановились на контроллере Home Center 2. Изначально планировалось создать сеть из пяти контроллеров и организовать систему таким образом, чтобы один контроллер управлял всеми квартирами на одном этаже здания. Но вскоре выяснилось, что таким образом построить систему не получится, так как у HC2 есть ограничение на количество подключенных z-wave устройств, а объединение контроллеров в одну сеть дает только расширение зоны действия z-wave сети, но не увеличивает предельно допустимое количество подключенных устройств. Одновременно к одному контроллеру можно подключить не больше 230 устройств. Соответственно, к пяти контроллерам, объединенным в единую сеть, по-прежнему можно подключить лишь 230 устройств. Поэтому нам пришлось увеличить количество контроллеров в проекте в два раза и отказаться от объединения их в единую сеть. Теперь один HC2 будет работать на 4-5 квартир, что дает нам возможность использовать от 46 до 57 z-wave устройств в каждой квартире.
После того, как мы определились с главным контроллером, встал вопрос, какие данные необходимо собирать, и как это делать. Для управления климатом необходимо знать текущее положение дел в квартире, а именно: температуру внутри и снаружи помещения, влажность, уровень CO2, положение окон и дверей, наличие жильцов дома. Поскольку бюджет проекта ограничен, мы отказались от мониторинга влажности и уровня CO2.
Для мониторинга температуры внутри помещения многие z-wave устройства содержат встроенные датчики температуры, дополняющие основной функционал устройства. И, конечно же, существуют датчики температуры в отдельном исполнении. Согласно нашему проекту, в каждой квартире будет примерно 35 устройств, которые так или иначе будут показывать значение температуры. Это три датчика протечки FIB_FGFS-101, три IR преобразователя REM_ZXT120, термостат RS 014G0160, датчики движения, и по три датчика температуры DS 18B20 на каждый контур теплого пола и контур системы отопления. Мониторинг температуры контура теплого пола необходим в первую очередь для того, чтобы не допустить перегрева паркета, т.к. максимально допустимая температура паркета не превышает 27 градусов.

Контроль температуры для защиты паркета от перегрева
Поскольку все эти значения температуры могут достаточно серьезно отличаться друг от друга, в зависимости от того, где устройство установлено – для определения температуры в помещении мы будем высчитывать среднее значение по всем показателям из данного помещения.
Для определения температуры снаружи помещения существуют два варианта. В HC2 есть функция получения прогноза погоды для города, который задается при первоначальной настройке контроллера. Однако такой метод определения температуры не отличается приемлемой точностью, поэтому мы для этих целей будем использовать несколько датчиков DS 18B20, установленных на внешнем фасаде здания. При этом следует учесть, что датчики нужно располагать не напрямую на фасаде и избегать попадания на них прямых солнечных лучей.
В любом умном доме одной из главных целей его создания является снижение затрат на обогрев и охлаждение помещений, поэтому очень важным становится понимание текущего положения окон и дверей. Для того чтобы отключать отопление и кондиционирование, если открыто окно или дверь, мы будем использовать обычные магнитно-контактные датчики, а для их интеграции в сеть z-wave они будут подключены к универсальным бинарным датчикам FIB_FGBS-001.

Подключение датчиков температуры DS18B20
Для определения наличия жильцов дома мы создали виртуальное устройство, которое представляет собой кнопку. При нажатии на эту кнопку пользователь сообщает системе, что дома никого нет.

Виртуальное устройство — кнопки включения режимов дом/работа
Когда в систему поступает сигнал, что дома никого нет, контроллер отключает все системы HVAC и переходит в режим энергосбережения до тех пор, пока пользователь не соберется домой. Находясь в режиме энергосбережения, система продолжает контролировать температуру, и не допустит переохлаждения помещений и снижения температуры ниже отметки в 18 градусов.
Еще один немаловажный элемент управления климатом в жилом помещении это уставка температуры. В нашем решении пользователи смогут изменять ее двумя способами. С помощью настенного термостата или при помощи специально созданного виртуального устройства используя смартфон или планшет.
Разобравшись с мониторингом текущего состояния микроклимата в квартире, мы перешли к изучению непосредственно тех устройств, которыми нам предстояло управлять.
Каждая квартира будет оборудована 3 кондиционерами производства Mitsubishi Еlectric. Управление ими планируется осуществлять при помощи IR преобразователей REM_ZXT120. Эти устройства имеют предустановленные настройки для управления наиболее распространенными моделями кондиционеров от ведущих производителей, а так возможность обучения IR командам с пульта дистанционного управления.
Помимо кондиционеров каждая квартира будет оснащена независимой системой приточно-вытяжной вентиляции, и управление ей будет организовано с использованием двухканальных реле FIB_FGS-222.
Также во всех квартирах будут установлены семь контуров теплого пола и один контур центрального отопления. Каждый контур оснащается трехпозиционным клапаном с сервоприводом. Управляется при помощи RGBW модуля FIB_FGRGB-101.
После подбора и изучения всего необходимого оборудования нашей следующей задачей стала разработка наиболее эффективного и самодостаточного алгоритма управления климатом.
Кликабельно:

На блок-схеме приведен алгоритм, который представляет собой основную логику работы всей системы управления HVAC.
Получившийся алгоритм реализован в виде одного главного скрипта и нескольких вспомогательных. В НС2 эти скрипты называются сценами и пишутся на lua.
Для того чтобы не сильно загружать контроллер, сцены запускаются только при срабатывании так называемых триггеров.
Для основной сцены в качестве триггеров выступают следующие события:
- один из показателей температуры изменится более чем на один градус
- пользователь изменил уставку температуры
- пользователь включил/выключил режим на работе
- окно или дверь (на лоджию или входная) были открыты/закрыты
Код основного скрипта
--[[ %% properties 3 Temperature --температура за окном 85 value --датчик температуры 1 86 value --датчик температуры 2 87 value --датчик температуры 3 %% events %% globals tempSet --]] local temp1 = tonumber(fibaro:getValue(85, "value")) -- датчик температуры 1 local temp2 = tonumber(fibaro:getValue(86, "value"))-- датчик температуры 2 local temp3 = tonumber(fibaro:getValue(87, "value"))-- датчик температуры 3 local tempOUT = tonumber(fibaro:getValue(3, "Temperature"))-- датчик температуры за окном local IDCooler = 99 -- вентиляция local IDCond = 100 -- кондиционер local IDCondHeat = 102 -- кондиционер обогрев (для тестирования) local IDFloor = 23 -- теплый пол local IDHeat = 24 -- радиатор local tempset = fibaro:getGlobalValue("tempSet") local workmode = fibaro:getGlobalValue("Workmode") local tempInside = (temp1 + temp2 + temp3) / 3 local date = os.date("!*t", now) local currtime = date.hour*60 + date.min --текущее время в минутах local d = tempset - tempInside local w = tempset - tempOUT --globals: -- Workmode -- TempSet -- WinStatus -- Isventnow -- CHeating local cHeating = "on" local winStatus = "closed" print("Starting Climate Control") print("t в помещении = "..tempInside..", t целевая = "..tempset) print("Workmode: "..workmode..", Windows: "..winStatus,", Central Heating: "..cHeating) --режим на работе включен if (fibaro:getGlobalValue("Workmode1") == "At work") then --если прохладно if (tempInside < 18) then --включить подогрев if (cHeating == "on") then -- включить радиаторы print("включить радиаторы") fibaro:call(IDHeat, "turnOn") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end fibaro:call(IDCondHeat, "turnOff") fibaro:call(IDCond, "turnOff") fibaro:call(IDFloor, "turnOff") elseif (windows == "closed") then -- включить кондиционер наобогрев print("включить обогрев кондиционера") fibaro:call(IDCondHeat, "turnOn") fibaro:call(IDCond, "turnOn") fibaro:call(IDFloor, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end fibaro:call(IDHeat, "turnOff") end --если жарко и радиаторы включены elseif (tempInside > 21) then --выключить радиаторы if(fibaro:getValue(IDHeat, value) >0) then print("выключить радиаторы") fibaro:call(IDHeat, "turnOff") else fibaro:call(IDCondHeat, "turnOn") fibaro:call(IDCond, "turnOn") fibaro:call(IDFloor, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end end end -- если достигли нужной температуры elseif d < 1 and d > -1 then print("выключаем всё") --выключить кондиционер fibaro:call(IDCondHeat, "turnOff") fibaro:call(IDCond, "turnOff") --выключить вентиляцию if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end --выключить радиаторы fibaro:call(IDHeat, "turnOff") --выключить теплый пол fibaro:call(IDFloor, "turnOff") -- если включено центральное отопление elseif (cHeating == "on") then --включено центральное отопление if (d >= 1) then --обогрев if (d <= 3) then print("включить теплый пол") --включить теплый пол fibaro:call(IDFloor, "turnOn") fibaro:call(IDCondHeat, "turnOff") fibaro:call(IDCond, "turnOff") fibaro:call(IDHeat, "turnOff") fibaro:call(IDCooler, "turnOff") elseif (d > 3) then print("включить теплый пол и радиаторы") --включить теплый пол fibaro:call(IDFloor, "turnOn") --включить радиаторы fibaro:call(IDHeat, "turnOn") fibaro:call(IDCondHeat, "turnOff") fibaro:call(IDCond, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end end elseif (d <= -1) then --охлаждение print("включить вентиляцию") -- включить вентиляцию if(Isventnow == "no") then fibaro:call(IDCooler, "turnOn") end lastCondition = currTime end --если выключено центральное отопление elseif (cHeating == "off") then --обогрев if (d >= 1) then if (w <= 0) then print("включить вентиляцию") -- включить вентиляцию if(Isventnow == "no") then fibaro:call(IDCooler, "turnOn") end fibaro:call(IDCondHeat, "turnOff") lastCondition = currTime elseif (d < 4) then print("включить вентиляцию") -- включить вентиляцию fibaro:call(IDCondHeat, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOn") end lastCondition = currTime elseif (winStatus == "closed") then print("включить кондиционер на обогрев") -- включить кондиционер на обогрев fibaro:call(IDCondHeat, "turnOn") fibaro:call(IDCond, "turnOn") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end end elseif (d <= -1) then --охлаждение if(w >= 0) then if(d > -4) then print("включить вентиляцию") -- включить вентиляцию if(Isventnow == "no") then fibaro:call(IDCooler, "turnOn") end fibaro:call(IDCondHeat, "turnOff") fibaro:call(IDCond, "turnOff") elseif (winStatus == "closed") then print("включить кондиционер") -- включить кондиционер fibaro:call(IDCond, "turnOn") fibaro:call(IDCondHeat, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end end elseif (winStatus == "closed") then print("включить кондиционер") -- включить кондиционер fibaro:call(IDCond, "turnOn") fibaro:call(IDCondHeat, "turnOff") if(Isventnow == "no") then fibaro:call(IDCooler, "turnOff") end end end end
Как видно из кода основной сцены, в своей работе она использует глобальные переменные:
- Workmode {«at work», «at home»} //режим на работе
- TempSet //температура уставки
- WinStatus {'opened", «closed»} //открыты ли окна и двери на лоджию (нужны для ограничения работы кондиционеров)
- CHeating {«on»,«off»} //включено ли центральное отопление
Мониторинг текущего положения окон и дверей в квартире будет осуществляться вспомогательной сценой. Результат ее работы хранится в глобальной переменной WinStatus. Так же отдельная сцена контролирует изменение температуры датчиков возле насосов центрального отопления в подвале здания и определяет включено ли центральное отопление. Результат ее работы хранится в глобальной переменной CHeating.
Так как для комфорта очень важно чтобы воздух в квартире был свежий, мы решили, что будет правильно сделать систему принудительного проветривания помещений через приточно-вытяжную вентиляцию. Если в течение последних трех часов вентиляция не работала, то автоматически запустится сценарий проветривания помещения длительностью 15 минут. Принудительное проветривание не осуществляется если включен режим «на работе».
Скрипт выполняющий принудительное проветривание
function vent_forced() local workmode = fibaro:getGlobal('Workmode') local isventnow = fibaro:getGlobal('Isventnow') local lastModified = fibaro:getGlobalModificationTime('Isventnow') if ((os.time() - lastModified) < 10800) then print ("время с последнего проветривания в секундах "..(os.time() - lastModified)) print ("с последнего проветривания прошло меньше 3-х часов") end if ( workmode == 'At home' and isventnow == 'no' and (os.time() - lastModified) > 10800 ) then print ("время с последнего проветривания в секундах "..(os.time() - lastModified)) fibaro:call(99, "turnOn") fibaro:setGlobal('Isventnow', 'yes') print ("с последнего проветривания прошло больше 3 часов") print ("принудительное проветривание помещения включено") fibaro:sleep(900000) fibaro:call(99, "turnOff") fibaro:setGlobal('Isventnow', 'no') print ("принудительное проветривание помещения выключено") end end local sourceTrigger = fibaro:getSourceTrigger() if (sourceTrigger["type"] == "autostart") then while true do fibaro:debug('Сцена запущена автоматически') local currentDate = os.date("*t") if (currentDate.min >= 0 and currentDate.min <= 60) then vent_forced() end fibaro:debug('Сцена отработала, следующий запуск через 1 час') fibaro:sleep(3600*1000) end end
Вот так мы планируем решать поставленную задачу. На повестке дня стоит еще много вопросов, предстоит решить много проблем и преодолеть множество трудностей. Это наша проба пера, просим вас отнестись с добротой и пониманием.
