Добрый день!
Прошу совета по скрипту.
Я написал скрипт для Лорана (http://www.kernelchip.ru/Laurent-2.php)
! ````
var IP = "192.168.0.104";
var Period = 5000;
! //Создаем переменные
createState('laurent.temperature','',{type:'number',role:'value.temperature',read:true,unit:'°C'});
createState('laurent.systemtime','',{type:'number',role:'value',read:true});
createState('laurent.inline1','',{type:'boolean',role:'state',read:true});
createState('laurent.inline2','',{type:'boolean',role:'state',read:true});
createState('laurent.inline3','',{type:'boolean',role:'state',read:true});
createState('laurent.inline4','',{type:'boolean',role:'state',read:true});
createState('laurent.inline5','',{type:'boolean',role:'state',read:true});
createState('laurent.inline6','',{type:'boolean',role:'state',read:true});
createState('laurent.relay1','',{type:'boolean',role:'switch',read:true,write:true});
createState('laurent.relay2','',{type:'boolean',role:'switch',read:true,write:true});
createState('laurent.relay3','',{type:'boolean',role:'switch',read:true,write:true});
createState('laurent.relay4','',{type:'boolean',role:'switch',read:true,write:true});
! var request = require('request');
! //Функция для извлечения значений из XML
function XMLElement(tag, xmlcontent)
{
var reg = "<"+tag+">(.*)";
return xmlcontent.match(reg)[1];
}
! //Функция для переключения реле - отослать команду
function relaySwitch (obj)
{
if (obj.state.ack === false && obj.state.val === true)
{
request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(/[1-9]/)+',1');
}
else if (obj.state.ack === false && obj.state.val === false)
{
request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(/[1-9]/)+',0');
}
}
! //Функция обработки ответа
function statusProcessing(error, response, body)
{
//Температура = Конвертируем строку в число (запрошенную по тегу temp в ответе Лорана).округляем (до 1 знака после запятой)
var temperature = parseFloat(XMLElement ("temp", body)).toFixed(1);
setState('laurent.temperature', parseFloat(temperature), true);
! //Время Лорана
setState('laurent.systemtime', parseInt(XMLElement ("systime", body)), true);
! //Строка состояния реле
var relayString = XMLElement ("rele", body);
var relayTable = relayString.split("");
//Запишем состояния в каждое реле
setState('laurent.relay1', Boolean(parseFloat(relayTable[0])), true);
setState('laurent.relay2', Boolean(parseFloat(relayTable[1])), true);
setState('laurent.relay3', Boolean(parseFloat(relayTable[2])), true);
setState('laurent.relay4', Boolean(parseFloat(relayTable[3])), true);
//Строка состояния входов
var inlineString = XMLElement ("in", body);
var inlineTable = inlineString.split("");
//Запишем состояния в каждый вход
setState('laurent.inline1', Boolean(parseFloat(inlineTable[0])));
setState('laurent.inline2', Boolean(parseFloat(inlineTable[1])));
setState('laurent.inline3', Boolean(parseFloat(inlineTable[2])));
setState('laurent.inline4', Boolean(parseFloat(inlineTable[3])));
setState('laurent.inline5', Boolean(parseFloat(inlineTable[4])));
setState('laurent.inline6', Boolean(parseFloat(inlineTable[5])));
}
! //Главная периодическая функция
function mainPoll ()
{
request ('http://'+IP+'/state.xml', statusProcessing);
}
! //Подписываемся на состояние реле/выключателя
on('javascript.0.laurent.relay1', relaySwitch);
on('javascript.0.laurent.relay2', relaySwitch);
on('javascript.0.laurent.relay3', relaySwitch);
on('javascript.0.laurent.relay4', relaySwitch);
! //Задаем выполенение функции через определенный интервал
var timerID = setInterval(mainPoll, Period);
В целом он работает нормально, за одним исключением.
Я думаю там понятно, но на всякий случай объясню поподробнее.
Актуальна работа реле. В Лоране их 4.
В интерфейсе создаются выключатели (объекты), там их 4.
Например первый выключатель, для реле 1 вот этот:
createState('laurent.relay1','',{type:'boolean',role:'switch',read:true,write:true});
Там есть функция, которая периодически вызывается, эта функция опрашивает Лоран, получает xml c состояниями, в том числе и реле:
function mainPoll ()
{
request ('http://'+IP+'/state.xml', statusProcessing);
}
Потом есть функция, которая парсит этот файл, узнает состояние реле, и записывает его в наш объект.
setState('laurent.relay1', Boolean(parseFloat(relayTable[0])), true);
Далее, мы хотим управлять реле.
Подписываемся на его состояние (объекта):
on('javascript.0.laurent.relay1', relaySwitch);
Функция проверяет, что состояние объекта было изменено, и если оно было изменено в интерфейсе (проверяет ack), то посылает http-команду Лорану.
function relaySwitch (obj)
{
if (obj.state.ack === false && obj.state.val === true)
{
request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(/[1-9]/)+',1');
}
else if (obj.state.ack === false && obj.state.val === false)
{
request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(/[1-9]/)+',0');
}
}
И это работает.
Но иногда возникает конфликт.
Например, реле выключено.
Включаешь в интерфейсе этот выключатель, соответствующий реле. Он нормально становится включенным, команда посылается, реле щелкает. Но видимо как раз в этот момент происходит опрос, в результате которого реле еще выключено. И состояние его в интерфейсе становится выключенным. Ну, и после следующего периода опроса становится нормальным (включенным).
Надеюсь, понятно объяснил.
Что можно сделать в этом случае?