Что имеем: новый контроллер "умного дома" Fibaro Home Center 3 (на частоте RU), а также 4 WiFi-модуля от UnitX: с простым датчиком температуры и с комбинированным датчиком температуры и влажности.
Что ожидаем: использовать имеющиеся датчики в связке с новым контроллером "умного дома".
Найденный вариант решения.
Имеющиеся модули UnitX умеют отправлять данные со своих датчиков либо в облако компании производителя, либо на произвольный сервер, настроенный пользователем по протоколу MQTT. Вариант через облако не дает возможности использования данных в сторонних приложениях, поэтому к выбору остается реализация обмена по протоколу MQTT.
Обзор Интернета дает массу вариантов реализации обмена через MQTT: от облачных серверов, до самостоятельного развертывания серверов MQTT на различных платформах (Desktop Windows, Linux, Raspberry PI и т.п.). Мне понравился вариант, изложенный в статье "Поднимаем личный MQTT сервер на роутере Keenetic", тем более что роутер Keenetic Giga имелся в наличии и как раз работал в сети, где разворачивался "умный дом". Выполнение рекомендаций из этой статьи позволили быстро и без дополнительных затрат получить работающий личный MQTT-сервер внутри используемой сети.
Следующий шаг: разобраться с тем, каким образом контроллер Fibaro HC3 умеет работать с MQTT в качестве клиента. И здесь все оказалось просто - вот документация с официального сайта документации Fibaro: [HC3, HC3L, YH] Quick Apps – MQTT client.
Все детали пазла сложились - теперь сама реализация.
- В разделе глобальных переменных панели управления контроллера HC3: General - Variables (Общее - Переменные) создаем несколько переменных для настройки взаимодействия контроллера HC3 с сервером MQTT:
- MQTT_Broker_URI - адрес для подключения к выбранному серверу MQTT;
- MQTT_Broker_Port - порт, на котором работает выбранный сервер MQTT (по умолчанию это 1883);
- MQTT_Broker_User - имя пользователя для авторизации на сервере MQTT; т.к. по непонятным причинам раздел глобальных переменных не поддерживает "секретные" переменные для хранения пароля, пароль для авторизации на сервере MQTT будет размещен в настройках конкретного устройства.
- Создаем новое "устройство" QuikApp в панели управления контроллером (не забудьте дать понятное уникальное имя данному "устройству"):
- Во вкладке Variables (Переменные) добавить и заполнить локальные переменные для настройки конкретного устройства:
- SensorName - имя устройства для представления на сервере MQTT - следует заполнять с использование соглашений для ClientID сервера MQTT;
- MQTT_Topic - наименование топика, в котором ожидается публикация данных соответствующим модулем UnitX - в соответствии с соглашениями на конкретном сервере MQTT; следует обратить внимание, что при настройке модуля UnitX для обмена с сервером MQTT необходимо указывать аналогичный топик, например: ; в таком случае в переменной MQTT_Topic можно указать такое же наименование или расширенное вида UNITX/001/#.
- sTimeout - таймаут в секундах между попытками реконнекта; возможно, этт параметр излишний и может быть исключен из настроек одновременно с соответствующим изменением в теле скрипта LUA.
- MQTT_Broker_PWD - пароль для авторизации на сервере MQTT; напомню, что имя пользователя для авторизации размещено в глобальных переменных настройки.
- Необходимо создать LUA-скрипт создаваемого "устройства" - во вкладке "Edit&Preview" - Edit - вместо шаблона "по-умолчанию" для "устройства" QuickApp следует вставить и сохранить приведенный ниже текст скрипта LUA:
- Текст скрипта LUA:
-- Temperature sensor type have no actions to handle
-- To update temperature, update property "value" with floating point number
-- Eg. self:updateProperty("value", 18.12)
-- To update controls you can use method self:updateView(<component ID>, <component property>, <desired value>). Eg:
-- self:updateView("slider", "value", "55")
-- self:updateView("button1", "text", "MUTE")
-- self:updateView("label", "text", "TURNED ON")
-- This is QuickApp inital method. It is called right after your QuickApp starts (after each save or on gateway startup).
-- Here you can set some default values, setup http connection or get QuickApp variables.
-- To learn more, please visit:
-- * https://manuals.fibaro.com/home-center-3/
-- * https://manuals.fibaro.com/home-center-3-quick-apps/
function QuickApp:subscribe()
self.client:addEventListener('message', function(event) self:onMessage(event) end)
self.client:addEventListener('subscribed', function(event) self:onSubscribed(event) end)
self:debug("subscribe")
self.client:subscribe(self.Topic, { qos = mqtt.QoS.EXACTLY_ONCE });
end
function QuickApp:onSubscribed(event)
self:debug("onSubscribed:" .. json.encode(event))
end
function QuickApp:onMessage(event)
local tt
local pp
self:debug("onMessage:" .. json.encode(event))
self:debug("onMessage:" .. json.encode(event.payload))
pp = json.decode(event.payload)
tt = tonumber(pp.t)
self:debug("onMessage: set value to " .. tt)
self:updateProperty("value", tt)
end
function QuickApp:onConnected(event)
self:debug("onConnected:" .. json.encode(event))
self:subscribe()
end
function QuickApp:connect()
self:debug("self:connect")
self.client = mqtt.Client.connect(
self.BrokerURI,
{
port = tonumber(self.BrokerPort);
username = self.BrokerUser;
password = self.BrokerPWD;
clientId = self.sName;
callback = function(errorCode)
self:debug("connect - callback - errorCode=" .. errorCode)
if errorCode ~= 0 then
self:connect()
end
end;
}
)
self.client:addEventListener('connected', function(event) self:onConnected(event) end)
end
function QuickApp:onInit()
self:debug("onInit")
self.Topic = self:getVariable("MQTT_Topic")
self:debug("MQTT_Topic=" .. self.Topic)
self.sName = self:getVariable("SensorName")
self:debug("SensorName=" .. self.sName)
self.sTimeout = tonumber(self:getVariable("sTimeout"))*1000
self:debug("sTimeout=" .. self.sTimeout)
self.BrokerURI = fibaro.getGlobalVariable("MQTT_Broker_URI")
self:debug("MQTT_Broker_URI=" .. self.BrokerURI)
self.BrokerPort = fibaro.getGlobalVariable("MQTT_Broker_Port")
self:debug("MQTT_Broker_Port=" .. self.BrokerPort)
self.BrokerUser = fibaro.getGlobalVariable("MQTT_Broker_User")
self.BrokerPWD = self:getVariable("MQTT_Broker_PWD")
self:debug("MQTT_Broker_User=" .. self.BrokerUser .. "/" .. self.BrokerPWD)
self:connect() -- соединение
fibaro.setTimeout(self.sTimeout, function()
self:connect()
end
)
end
ВСЁ!
После сохранения скрипта "устройство" уже начинает работать, ожидая публикации соответствующих данных - отладочную информацию о работе устройства можно увидеть в окне консоли.
PS. Заметил, что при интенсивной работе в панели управления контроллера HC3 при отладке LUA-скриптов, у меня периодически "подвисает" сама панель управления. Лечится переподключением к панели управления.
Автор: Александр Солнцев