-
Vital
-
-
Вне сайта
-
Укротитель реле
-
-
Vera 3 и Vera Edge
- Сообщений: 376
- Спасибо получено: 79
-
Репутация: 9
-
|
Итак, сделал я следующим образом.
Основной файл - I:
<?xml version="1.0"?>
<implementation>
<functions>
function initialisation(lul_device) -- функция для начального запуска
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",0,lul_device) -- Стандартную переменную состояния выключателя делаем 0
-- Переменные определены в S-файле
-- Записываем переменные в 0 или unknown, если они не имели значения
-- Без этого переменные не видны в веб-интерфейсе Веры
local IP = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentIP", lul_device)
if (IP == nil) then
luup.variable_set("urn:upnp-org:serviceId:Laurent1", "LaurentIP", "unknown", lul_device)
end
local Port = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentPort", lul_device)
if (Port == nil) then
luup.variable_set("urn:upnp-org:serviceId:Laurent1", "LaurentPort", "unknown", lul_device)
end
local Relay = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "RelayID", lul_device)
if (Relay == nil) then
luup.variable_set("urn:upnp-org:serviceId:Laurent1", "RelayID", "0", lul_device)
end
local Period = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "Period", lul_device)
if (Period == nil) then
luup.variable_set("urn:upnp-org:serviceId:Laurent1", "Period", "0", lul_device)
end
local Password = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "Password", lul_device)
if (Password == nil) then
luup.variable_set("urn:upnp-org:serviceId:Laurent1", "Password", "unknown", lul_device)
end
-- Проверяем состояние модуля
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:settimeout(1)
tcp:connect(IP, Port)
tcp:send("$KE".."\r\n")
local ModuleStatus = tcp:receive()
luup.sleep(50)
tcp:close()
luup.sleep(50)
-- Пишем состояние модуля в лог
luup.log("Laurent "..IP.." - Module Status - "..ModuleStatus)
-- Запускаем функцию запроса с отложенным действием. Не знаю зачем, но так надо
luup.call_timer("request", 1, Period, "")
function request()
-- Запрашиваем значения переменных
local IP = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentIP", lul_device)
local Port = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentPort", lul_device)
local Relay = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "RelayID", lul_device)
-- Осуществляем собственно сам запрос и результат пишем в переменную RelayStatus
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:settimeout(1)
tcp:connect(IP, Port)
-- Сначала отправляем пароль
tcp:send("$KE,PSW,SET,"..Password.."\r\n")
local PasswordStatus = tcp:receive()
luup.sleep(50)
-- Пишем ответ в лог
luup.log("Laurent "..IP.." - Password Status when ask codition - "..PasswordStatus)
luup.sleep(200)
tcp:send("$KE,RDR,"..Relay.."\r\n")
local RelayStatus = tcp:receive()
luup.sleep(50)
tcp:close()
luup.sleep(50)
-- Пишем в лог состояние реле
luup.log("Laurent "..IP.." - Relay Status - "..RelayStatus)
-- Сравниваем полученный ответ с ожидаемым результатом
-- Если ответ что реле включено - задаем его состояние 1 в переменной устройства
if (RelayStatus == "#RDR,"..Relay..",1") then
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",1,27)
-- Иначе - задаем его состояние 0 в переменной устройства
else
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",0,27)
end
-- Функция сама себя перезапускает через указанный период времени
luup.call_timer("request", 1, Period, "")
end
end
</functions>
<startup>initialisation</startup> -- функция, запускаемая при старте движка
<actionList>
<action>
<serviceId>urn:upnp-org:serviceId:SwitchPower1</serviceId>
<name>SetTarget</name>
<run>
-- Запрашиваем состояние реле (не реальное, а сохраненное в Вере)
local switchOnOff = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", lul_device)
-- Запрашиваем переменные
local IP = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentIP", lul_device)
local Port = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "LaurentPort", lul_device)
local Relay = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "RelayID", lul_device)
local Password = luup.variable_get("urn:upnp-org:serviceId:Laurent1", "Password", lul_device)
-- Если было включено - то выключаем так
if (switchOnOff == "1") then
-- Сначала пишем в переменну состояние для правильного отображения
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",0,lul_device)
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:settimeout(1)
tcp:connect(IP, Port)
-- Сначала отправляем пароль
tcp:send("$KE,PSW,SET,"..Password.."\r\n")
local PasswordStatus = tcp:receive()
luup.sleep(50)
-- Пишем ответ в лог
luup.log("Laurent "..IP.." - Password Status when turn off - "..PasswordStatus)
luup.sleep(200)
tcp:send("$KE,REL,"..Relay..",0".."\r\n")
local TurnOffAnswer = tcp:receive()
-- Пишем ответ в лог
luup.log("Laurent "..IP.." - Answer when turn off - "..TurnOffAnswer)
luup.sleep(50)
tcp:close()
-- Иначе - включаем так
else
-- Сначала пишем в переменну состояние для правильного отображения
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",1,lul_device)
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:settimeout(1)
tcp:connect(IP, Port)
-- Сначала отправляем пароль
tcp:send("$KE,PSW,SET,"..Password.."\r\n")
local PasswordStatus = tcp:receive()
luup.sleep(50)
-- Пишем ответ в лог
luup.log("Laurent "..IP.." - Password Status when turn on - "..PasswordStatus)
luup.sleep(200)
tcp:send("$KE,REL,"..Relay..",1".."\r\n")
local TurnOnAnswer = tcp:receive()
-- Пишем ответ в лог
luup.log("Laurent "..IP.." - Answer when turn on - "..TurnOnAnswer)
luup.sleep(50)
tcp:close()
end
</run>
</action>
</actionList>
</implementation>
Все работает нормально. Можно отключить и включить, реальное состояние тоже опрашивается. Сделал с помощью функции luup.call_timer, которая когда выполняется - то сама себя перевызывает с задержкой (как-то так).
Но сразу скажу, что я понял, что все придется переделывать, но как временное решение - пойдет, и, может быть, кому-нибудь мои изыскания пригодятся.
Вот мои файлы устройства: D, I и S: cloud.mail.ru/public/GQwf/RyzSkDqig
Я там сделал даже проверку доступности реле перед запуском и использование пароля.
Создаем устройство через Apps -> Develop apps -> Create device
Переменные вводятся в настройках устройства.
Итак, в чем же проблема и почему надо делать иначе.
Это одно реле, а ведь мне надо опрашивать несколько. И еще датчики опрашивать. И если выключатель можно опросить раз в минуту, то некоторые датчики надо раз в секунду. Т.е. там получится каша из запросов и ответов, они будут мешаться друг другу. Каждый раз при запросе открывается сокет, и значит другой запрос уже не сможет сокет открыть. Так что это не прокатит.
|