«Грей, дуй, охлаждай…», или логика управления климатом в умном доме

в 14:21, , рубрики: diy или сделай сам, Fibaro, hvac, z-wave, Программирование, умный дом, умный дом z-wave, управление климатом
Умный дом

В последнее время тематика умного дома набирает все большую популярность, появляются все новые и новые статьи, отзывы, обсуждения, и практически на любой вопрос можно сходу найти несколько мнений и ответов. Но во всем этом мире информации по-прежнему остается одна белая область, а именно логика работы. Мы не побоялись и решили представить на суд общественности наши заготовки по этому вопросу.

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

В качестве основных требований заказчик отметил: единый интерфейс для управления всеми системами умного дома, ограниченный бюджет и минимальное количество дополнительной проводки. После небольшого исследования рынка систем автоматизации мы остановились на решении от 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

Подключение датчиков температуры 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

Вот так мы планируем решать поставленную задачу. На повестке дня стоит еще много вопросов, предстоит решить много проблем и преодолеть множество трудностей. Это наша проба пера, просим вас отнестись с добротой и пониманием.

Автор: Draftt

Источник


  1. Алексей:

    Здравствуйте. Прошло уже три года…. Удалось ли реализовать проект?

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js