Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Русский
    3. ioBroker
    4. Скрипты
    5. ioBroker скрипты
    6. Скрипт для Лоран

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Скрипт для Лоран

    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      Vital last edited by

      Добрый день!

      Прошу совета по скрипту.

      Я написал скрипт для Лорана (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');
      
      }
      
      }
      
      И это работает.
      
      Но иногда возникает конфликт.
      
      Например, реле выключено.
      
      Включаешь в интерфейсе этот выключатель, соответствующий реле. Он нормально становится включенным, команда посылается, реле щелкает. Но видимо как раз в этот момент происходит опрос, в результате которого реле еще выключено. И состояние его в интерфейсе становится выключенным. Ну, и после следующего периода опроса становится нормальным (включенным).
      
      Надеюсь, понятно объяснил.
      
      Что можно сделать в этом случае?
      1 Reply Last reply Reply Quote 0
      • V
        Vital last edited by

        Подправил скрипт, так работает лучше.

        Может кому пригодится.

        Скрипт разделен на две части, одна кладется в Global. В основном это для того, чтобы можно было опрашивать несколько Лоранов, копируя скрипт (у меня 3 штуки, например).

        ! ````
        var IP = "192.168.0.104";
        var Period = 5000;
        var laurentID = "000";
        ! //Функция в "global" для создания
        createMain ();
        ! var request = require('request');
        ! //Определяем переменные снаружи функции (чтобы были видны снаружи функции)
        var relayString = "0000";
        var inlineString = "000000";
        var outlineString = "000000000000";
        ! //Функция обработки ответа
        function statusProcessing(error, response, body)
        {
        if (!error && response.statusCode == 200)
        {
        setState('laurent'+laurentID+'.connectIndicator', true, true);

            //Температура = Конвертируем строку в число (запрошенную по тегу temp в ответе Лорана).округляем (до 1 знака после запятой)
            var temperature = parseFloat(XMLElement ("temp", body)).toFixed(1);
            setState('laurent'+laurentID+'.temperature', parseFloat(temperature), true);
        
            //Время Лорана
            setState('laurent'+laurentID+'.systemtime', parseInt(XMLElement ("systime", body)), true);
        

        ! //Строка состояния реле
        relayString = XMLElement ("rele", body);
        setState('laurent'+laurentID+'.relayString', relayString);

            //Строка состояния входов
            inlineString = XMLElement ("in", body);
            setState('laurent'+laurentID+'.inlineString', inlineString);
        
            //Строка состояния выходов
            outlineString = XMLElement ("out", body);
            setState('laurent'+laurentID+'.outlineString', outlineString);
        }
        else
        {
            setState('laurent'+laurentID+'.connectIndicator', false, true);
        }
        

        }

        ! //Главная периодическая функция
        function mainPoll ()
        {
        request ('http://'+IP+'/state.xml', statusProcessing);
        }
        ! //Подписываемся на состояние вспомогательно объекта (строки состояния) реле
        on('javascript.0.laurent'+laurentID+'.relayString', updateRelaysStates);
        ! //Подписываемся на состояние вспомогательно объекта (строки состояния) входных линий
        on('javascript.0.laurent'+laurentID+'.inlineString', updateInlinesStates);
        ! //Подписываемся на состояние вспомогательно объекта (строки состояния) выходных линий
        on('javascript.0.laurent'+laurentID+'.outlineString', updateOutlinesStates);
        ! //Подписываемся на состояние реле/выключателя (для управления из визуализации)
        on('javascript.0.laurent'+laurentID+'.relay1', relaySwitch);
        on('javascript.0.laurent'+laurentID+'.relay2', relaySwitch);
        on('javascript.0.laurent'+laurentID+'.relay3', relaySwitch);
        on('javascript.0.laurent'+laurentID+'.relay4', relaySwitch);
        ! //Подписываемся на состояние выходной линии/выключателя (для управления из визуализации)
        on('javascript.0.laurent'+laurentID+'.outline1', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline2', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline3', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline4', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline5', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline6', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline7', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline8', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline9', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline10', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline11', outlineSwitch);
        on('javascript.0.laurent'+laurentID+'.outline12', outlineSwitch);
        ! //Callback-функции находятся в "global"
        ! //Задаем выполнение функции через определенный интервал
        var timerID = setInterval(mainPoll, Period);

        
        И вот это в Global:
        
        >! ````
        function updateInlinesStates ()
        {
            var inlineTable = inlineString.split("");
            setState('laurent'+laurentID+'.inline1', Boolean(parseFloat(inlineTable[0])), true);
            setState('laurent'+laurentID+'.inline2', Boolean(parseFloat(inlineTable[1])), true);
            setState('laurent'+laurentID+'.inline3', Boolean(parseFloat(inlineTable[2])), true);
            setState('laurent'+laurentID+'.inline4', Boolean(parseFloat(inlineTable[3])), true);
            setState('laurent'+laurentID+'.inline5', Boolean(parseFloat(inlineTable[4])), true);
            setState('laurent'+laurentID+'.inline6', Boolean(parseFloat(inlineTable[5])), true);
        }
        >! function updateOutlinesStates ()
        {
            var outlineTable = outlineString.split("");
            setState('laurent'+laurentID+'.outline1', Boolean(parseFloat(outlineTable[0])), true);
            setState('laurent'+laurentID+'.outline2', Boolean(parseFloat(outlineTable[1])), true);
            setState('laurent'+laurentID+'.outline3', Boolean(parseFloat(outlineTable[2])), true);
            setState('laurent'+laurentID+'.outline4', Boolean(parseFloat(outlineTable[3])), true);
            setState('laurent'+laurentID+'.outline5', Boolean(parseFloat(outlineTable[4])), true);
            setState('laurent'+laurentID+'.outline6', Boolean(parseFloat(outlineTable[5])), true);
            setState('laurent'+laurentID+'.outline7', Boolean(parseFloat(outlineTable[6])), true);
            setState('laurent'+laurentID+'.outline8', Boolean(parseFloat(outlineTable[7])), true);
            setState('laurent'+laurentID+'.outline9', Boolean(parseFloat(outlineTable[8])), true);
            setState('laurent'+laurentID+'.outline10', Boolean(parseFloat(outlineTable[9])), true);
            setState('laurent'+laurentID+'.outline11', Boolean(parseFloat(outlineTable[10])), true);
            setState('laurent'+laurentID+'.outline12', Boolean(parseFloat(outlineTable[11])), true);
        >! }
        >! //Функция для переключения реле - отослать команду
        function relaySwitch (obj)
        {
            var reg = "relay([1-9])";
            if (obj.state.ack === false && obj.state.val === true)
            {
                request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(reg)[1]+',1');
            }
            else if (obj.state.ack === false && obj.state.val === false)
            {
                request ('http://'+IP+'/cmd.cgi?cmd=REL,'+obj.id.match(reg)[1]+',0');
            }
        }
        >! //Функция для переключения выходной линии - отослать команду
        function outlineSwitch (obj)
        {
            var reg = "outline([1-9]*)";
            if (obj.state.ack === false && obj.state.val === true)
            {
                request ('http://'+IP+'/cmd.cgi?cmd=OUT,'+obj.id.match(reg)[1]+',1');
            }
            else if (obj.state.ack === false && obj.state.val === false)
            {
                request ('http://'+IP+'/cmd.cgi?cmd=OUT,'+obj.id.match(reg)[1]+',0');
            }
        }
        
        1 Reply Last reply Reply Quote 0
        • First post
          Last post

        Support us

        ioBroker
        Community Adapters
        Donate

        858
        Online

        31.8k
        Users

        80.0k
        Topics

        1.3m
        Posts

        1
        2
        1014
        Loading More Posts
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes
        Reply
        • Reply as topic
        Log in to reply
        Community
        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
        The ioBroker Community 2014-2023
        logo