Arduino, ESP8266 Lua, Raspberry Pi 2 && OpenHab. Умный дом: азы управления.

Тема в разделе "Глядите, что я сделал", создана пользователем ИгорьК, 12 май 2015.

  1. alp69

    alp69 Форумчанин

    Сложно пробовать. Один брокер в Мурманске, другой в Ярославле. Причем ярославский чаще лежит по причине неустойчивого канала с инетом. Хотя... есть у меня еще одна Малина-3 ;) Как знал - в отпуске две купил на всякий случай :D
     
  2. ИгорьК

    ИгорьК Гуру

    Например:
    [​IMG]

    OpenHab/wi-fi <=> wi-fi/ESP-8266/HC-12 <=> HC-12/IskraJS

    А при чем здесь два брокера?
     
    Последнее редактирование: 23 сен 2016
    alp69 нравится это.
  3. ИгорьК

    ИгорьК Гуру

    Я тоже размышлял на тему двух брокеров, но отказался от нее. Если связь есть - она есть. Нет - зачем два брокера...
    Что касается падающего ярославского, то он, видимо, обслуживает что-то внутри домика родителей?
    Посмотрите вот на что - москиты могут обмениваться информацией, осуществляя взаимную подписку.
    Есть связь - обмениваются, нет - работают каждый и без этого.
     
    alp69 нравится это.
  4. alp69

    alp69 Форумчанин

    Вот это интересно. Где почитать?
    Если я правильно понял - esp выполняет функцию ретранслятора на направлении Искра-ОН? Или искра и есп параллельно держат связь с ОН но разными способами (2,4 ГГц и 433 МГц)?
     
  5. ИгорьК

    ИгорьК Гуру

    Откуда у Искры 2.4 ГГц? Она у меня в погребе вентилятор дует, и там wi-fi не работает, а 433 - очень даже уверенно.
     
    alp69 нравится это.
  6. alp69

    alp69 Форумчанин

    В смысле Искра - 433, а есп 2,4.
    Тогда замысел понятен. Надо брать на вооружение.
     
  7. ИгорьК

    ИгорьК Гуру

    Я картинку выше нарисовал.
     
    alp69 нравится это.
  8. dimm71

    dimm71 Нерд

    Всем привет.
    Воодушевившись темой умного дома, загорелся сделать недельный таймер с включением и отключением по времени в разные дни недели по разному. На просторах интернета ничего подобного не нашел. Смотрел про будильник, который включает свет, но это совсем не то. Сейчас объясню что хотелось бы иметь на выходе. В двух словах - недельный таймер. Сейчас объясню подробнее... Есть у меня в аквариуме скиммер и его крайне не желательно отключать вообще. Т.е. он должен работать постоянно - иначе беда (кислорода не хватает). Но так как аквариум стоит в детской комнате и всё же издает некоторый шум, приходится его на ночь отключать, а утром, как ребенок проснется, включать. Естественно это время разное. Сейчас там стоит розеточный таймер, но каждый день приходится его вручную включать/отключать. Ну, или почти каждый день. А с реализацией "Умного дома", думаю, было бы намного удобнее управлять таймерами включения/выключения. Понимаю, что требований к такому таймеру много есть. Например, при отключении эл-ва он должен запускаться, не сбрасывать таймер, восстанавливать время и т.д. и т.п.
    Может кто-нибудь встречал подобные проекты? Поделитесь ссылкой, пожалуйста. Или может у кого наработки уже есть.
     
  9. ИгорьК

    ИгорьК Гуру

    Есть такое явление: cron. Он есть в Openhab в частности и еще в любой Linux системе в целом.
    Поразбирайтесь. Все что Вы описали - реализуемо.
     
  10. ИгорьК

    ИгорьК Гуру

    39.2. Заводим HC-12 в OpenHab. ESP-8266.


    Предыдущий топик касался работы только с одним модулем (и у меня сейчас он один). А дальше?
    Дальше надо решить вопросы, связанные с упорядочиванием высказываний оконечных устройств с мест: только по запросу.
    Предлагаю решение. Железная часть - та же:
    [​IMG]
    В мастер-юните появляется таблица опроса устройств. Устройства сообщают о своем состоянии только по запросу мастера. В горячем режиме можно добавлять и удалять в таблицу имена устройств для опроса через (наш любимый) MqttSpy.
    После добавления или удаления мастер публикует json-стринг состояния таблицы опроса.
    Последний элемент в таблице удалить не удастся.
    Об этом и рассказывает художественный фильм. А в подстрочнм переводе это выглядит так (как наиграемся, удаляем все print кроме двух. Тех, что к информации ";" добавляют):
    Код (Lua):

    crc8 = require 'crc8'
    Broker="ВАШ_САЙТ"
    port=ВАШ_ПОРТ
    myClient="master433"
    pass="pass"
    publish = false
    asked = {
      '"cel"',
      --'"bel"',
      --'"gal"'
    }
    m = mqtt.Client(myClient, 180, myClient, pass)
    m:lwt("/lwt", myClient, 0, 0)
    function connecting()
      print('(Re)Connecting')
      function getConnect()
      if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
      print("Got WiFi!")
      m:connect(Broker, port, 0, 0,
      function(conn)
      tmr.stop(6)
      print("Connected")
      publish = true
      m:subscribe(myClient.."/#",0, function(conn)
      print("Subscribed")
      end)
      end)
      end
      end
      getConnect()
      tmr.alarm(6, 90000, 1, function()
      getConnect()
      end)
    end
    m:on("offline", function(con)
      publish = false
      connecting()
    end)
    function publ(dt) -- здесь разбираем данные от HC-12
      print('Now: '..dt)
      dt = string.gsub(dt, "%c","") -- удаляем все незнаки

      local data = crc8.decode(dt) -- проверяем crc8
      print("Got "..data)

      if data == 'NoCRC' then
      return
      end
      local topic = "/" -- формируем топик
      if string.find(data, "{") and string.find(data, "}") then
      print('Got JSON')
      local tp = cjson.decode(data)
      local top = tp.unt
      if top then
      topic = topic..top -- из названия оконечного устройства.
      else
      print("No topic")
      return
      end
      if publish == true then
      print("Publish!: ".. data)
      m:publish(myClient..topic,data,0,0)

      end
      end
      collectgarbage()
    end
    uart.on("data",';',
      function(data)
      if string.find(data, ";") then
      print('ask: '..data)
      data = string.gsub(data, ";","")
      data = string.gsub(data, "\n","")
      if string.find(data, "999") then -- Это для настройки, чтобы
      node.restart() -- перегружать было легче, удалить
      end -- весь  этот пассаж
      publ(data)
      end
    end, 0)
    m:on("message", function(conn, topic, data)
      if (string.find(topic, "state")) == nil then
      local top = string.gsub(topic, myClient.."/","")
      if top == "command" then
      local dt = crc8.encode(data)
      print(dt..";")
      end
      if top == "insert" then move(data, 1) end
      if top == "remove" then move(data, 0) end
      end
      collectgarbage()
    end)
    function move(ask, muv) -- функция вставляет и удаляет названия устройств в таблицу хапроса
      local place = 0
      muv = muv or 0
      print(cjson.encode(asked))
      for n, d in pairs(asked) do
      if d == ask then place = n end
      end
      if place ~= 0 and muv == 0 and #asked > 1 then
      table.remove(asked, place)
      end
      if place == 0 and muv == 1 then
      table.insert(asked, ask)
      end
      print(cjson.encode(asked))
      m:publish(myClient.."/report",json,0,0)
    end
    function AskUnits()  -- крутится для выдачи равномерных запросов конечным устройствам
      local count = 0
      local function AskNow()
      tmr.alarm(5, 30000, 1, function() -- через 30 сек следующий запросов
      if publish then  -- опрашиваем, если со Интернет все нормально
      count = count + 1
      if count > #asked then count = 1 end
      local ask = "{"..asked[count]..":0}"
      local send = crc8.encode(ask)
      print(send..';')
      end
      AskNow()
      end)
      end
      AskNow()
    end
    AskUnits()
    connecting()
     
     
    Последнее редактирование: 29 сен 2016
  11. dimm71

    dimm71 Нерд

    Можете привести небольшой примерчик? Или ссылку на образец?
     
    Последнее редактирование: 23 сен 2016
  12. ИгорьК

    ИгорьК Гуру

    1. Разбираетесь здесь.
    2. Потом здесь. В этом топике пример cron встречается 6 раз.
     
  13. ИгорьК

    ИгорьК Гуру

    Хозяйке на заметку. Строим прошивку ESP-8266 c json.
    Возможно, поможет кому-то. Hадеюсь, со временем проблему устранят.
    12345.jpg
     
    Последнее редактирование: 28 сен 2016
  14. kongen

    kongen Нерд

    Для себя сделал так:
    Код (Text):
    Group MyWeather
        Number    YandexTemp    "Температура [%.1f °C]"    <temperature>    { http="<[http://export.yandex.ru/bar/reginfo.xml?region=14.xml:30000:REGEX(.*?</pressure>.*<temperature.*>(.*?)</temperature>.*<time_zone>.*?)]" }
        Number    YandexHumi    "Влажность [%s %%]"    <humidity>    { http="<[http://export.yandex.ru/bar/reginfo.xml?region=14.xml:120000:REGEX(.*?<dampness>(.*?)</dampness>.*)]" }
        Number    YandexWind    "Ветер [%.1f м/с]"    <wind>                { http="<[http://export.yandex.ru/bar/reginfo.xml?region=14.xml:120000:REGEX(.*?<wind_speed>(.*?)</wind_speed>.*)]" }
        Number    YandexPress   "Давление [%d mm.Hg]"    { http="<[http://export.yandex.ru/bar/reginfo.xml?region=14.xml:120000:REGEX(.*?<pressure>(.*?)</pressure>.*)]" }
        String    YandexType    "За окном [%s]"    { http="<[http://export.yandex.ru/bar/reginfo.xml?region=14.xml:30000:REGEX(.*?<weather_type>(.*?)</weather_type>.*)]" }
     
    ИгорьК нравится это.
  15. ИгорьК

    ИгорьК Гуру

    Вынес в заголовок.

    Долго работает? Я временно отказался от Яндекса - то страницу не выдает, то вооще куда-то девается... Можно вернуться, полагаете?
     
    Последнее редактирование: 28 сен 2016
  16. kongen

    kongen Нерд

    Вроде все работает нормально. Понаблюдаю повнимательней и отпишусь.
     
  17. ИгорьК

    ИгорьК Гуру

    40.1. Вентиляция погреба.
    Выглядит это так:
    77352.jpg
    Как делалось железо - здесь.
    Устройство завязано на управляющую железку из предыдущего пункта, а сделано на Iskra JS.

    Джедаям, победившим ESP-8266 на Lua, никакой JavaScript не страшен, ибо на уровне железа IoT они мало чем друг от друга отличаются. Небольшие отличия в синтаксисе, а логика (начального уровня) одинаковая.
    Библиотека (библиотеки) для расчета crc8 сложена здесь.
    Код.
    Код (C++):
    // Loaded 05/09/2016

    var cl = console.log;
    var lcd = require("HD44780").connect(B0,C2,C9,C8,C7,C6);
    var crc8 = require("crc8").connect();
    var unt = "cel";    // Units Name

    /********************* Global Var init ****************************/
    var pinOW    = A3;    // DS18B20 pin
    var pinHumIn = A4;    // Humidity In pin
    var pinHumOt = A5;    // Humidity Out pin


    // For My Islra JS
    var MySerial = Serial4;
    var pinFan   = P2;    // Fan pin


    //var pinFan   = B1;    // Fan pin


    var makeDes  = 25;    // Delay in seconds to check sensors and make decision to switch fan

    var lagOn = 0.5;        // g/m3, Histeresis between humidityes to on fan
    var lagOff = 0.1;        // g/m3, Histeresis between humidityes to off fan

    var minInTemp = 3;    // Minimun inner temperature at cellar
    var maxOutTemp = 12; // Maximum Out temperature when fan cwitched ON

    var param = {
        unt : "cel",
        mod : "ON",
        fan : "OFF",
        faF : "OFF",    // Fan is forced switched
        tg : 4,            // Target temperature at cellar
        tIn : 16.4,        // Temperature at Cellar
        hIn : 95.3,        // Humidity at Cellar
        tOt : 10.8,        // Outside Temperature
        hOt : 20.4            // Outside Humidity
    };

    /************************  Just Switch The Fan  ************************/
    function SwitchFan(sw) {
        digitalWrite(pinFan, sw);
        if(sw) {param.fan = "ON";}
        else {param.fan = "OFF";}
        //cl("Fan is ", sw);
        // SendData("fan:"+param.fan);
    }

    /************************ Is It Time To Fan  ***************************/

    //------------------------ Print LCD ----------------------------

    function printLCD(aIn, aOut, inf) {
        if(inf) {
            lcd.clear();
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("    Cellar 80");
            lcd.setCursor(0,1);
            lcd.print("     Jiaffe!");
        }
        else {
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(param.tIn.toFixed(1)+"/"+param.hIn.toFixed(0)+"="+aIn.toFixed(0));
            lcd.setCursor(13,0);
            lcd.print("F:");
            if (param.fan === "ON"){
                lcd.print("\u00D9");
                x = true;
            }
            else {
                x = false;
                lcd.print("\u008D");
            }
            lcd.setCursor(13,1);
            lcd.print("M:");
            if (param.mod === "ON"){
                lcd.print("\u0094");
            }
            else {
                lcd.print("\u008D");
            }
            lcd.setCursor(0,1);
            lcd.print(param.tOt.toFixed(1)+"/"+param.hOt.toFixed(0)+"="+aOut.toFixed(0));
        }
    }


    var x = false;
    var pr = ['+', '/','X', '+','\\','X'];
    var nw = 0;

    var c = setInterval(function(){
      if(x) {
        lcd.setCursor(15,0);
        lcd.print(pr[nw]);
        nw++;
        if(nw === 6) nw = 0;
      }
    }, 150);


    //-------------------------  UART Init -------------------------------
    //var MySerial = Serial6;
    MySerial.setup(9600);
    var getUART = false;
    var inByte = "";
    var command = "";

    //-----------------------  UART Send --------------------------------

    function SendData (dt)  {
        var d = JSON.stringify(dt);
        var codeddt = crc8.encode(d);
        MySerial.print(codeddt+";");
        //cl("Sent "+d.length+" bytes: ", codeddt+";");
    }

    function SlowSendData() {
        setTimeout(function(){
            SendData(param);
        }, 500);
    }

    //--------------------  UART Received -----------------------------------

    // For tests
    // cl(crc8.encode('{"cel":1,"tg":7}'))
    // Serial6.emit('data', '{"cel":0}139#29;');
    // MySerial.emit('data', '{"cel":1,"faF":"ON"}44#189;');
    // {"cel":1,"tg":7}199#105;
    // {"cel":1,"mod":"OFF"}226#245;
    // MySerial.emit('data', '{"mod":"OFF"}181#62;')
    // is bad {"cel":1,"faF":"OFF"}44#189;
    // is long {"cel":1,"faF":"OFF"}44#1897;


    MySerial.on('data', function(data) {
        inByte = data;
        if (inByte.charCodeAt(0) === 123) { // This is  "{"
            command = "";
            getUART = true;
        }
        if (getUART === true) {
          command += inByte;
          if(command.length > 55) {  // Too long command should be terminated
            getUART = false;
          }
          var stopNow = command.indexOf(';');
          if (stopNow > 0) {
            GetCom(command.substring(0,stopNow));
            getUART = false;
          }
        }
    });

    function GetCom (packet) {
        //var SwitchFan = SwitchFan;
        // cl("GetCom", packet);
        if (packet.indexOf(unt) === -1 ){
            //cl("Not My Comm!");
            return;
        }
        aa = crc8.decode(packet);
        //cl("crc8 Report = ", aa);
        if (aa.indexOf("CRC") > 0 ){
            return;
        }

        var dd = JSON.parse(aa);
        //cl(dd);
        if(dd[unt] === 0) {
            //cl("Ask Me a Data!");
            // Answer:
            SlowSendData();
            return;
        }

        if (dd.hasOwnProperty("faF")) {
            //cl("Got faF");
            if (dd.faF === "ON") {
                SwitchFan(1);
                param.mod = "OFF";
                param.faF = "ON";
            }
            else {
                SwitchFan(0);
                param.mod = "ON";
                param.faF = "OFF";
            }
        }
        if (dd.hasOwnProperty("mod")) {
            //cl("Got mod");
            if (dd.mod === "ON") {
                param.mod = "ON";
                param.faF = "OFF";
            }
            else {
                SwitchFan(0);
                param.mod = "OFF";
                param.faF = "OFF";
            }
        }

        if (dd.hasOwnProperty("tg")) {
            //cl("Got tg");
            param.tg = parseInt(dd.tg, 10);
        }
        //cl(param);
    }


    //------------------------  DS18B20 Init ---------------------------

    var ow = new OneWire(pinOW);
    var sensor1 = require("DS18B20").connect(ow, 0);
    var sensor2 = require("DS18B20").connect(ow, 1);


    //----------------------------  GetSensors ---------------------------
    function GetSensors(callback) {
        var tInn = 85;
        var tOut = 85;
        //cl("GetSensors");

        var GetHue = function (pin, temp) {
            var RH =  (analogRead(pin) - 0.1515)/ 0.00636;
            var TrueRH = (RH)/(1.0546 - 0.00216 * temp);
            //cl("Hum is " + TrueRH.toFixed(1)+" %");
            return parseFloat(TrueRH.toFixed(1));
        };

        sensor1.getTemp(function (tInn) {
            //cl("Temp is "+tInn.toFixed(1)+" C");
            param.tIn = parseFloat(tInn.toFixed(1));
            var gin = GetHue;
            param.hIn = gin(pinHumIn, tInn);

            sensor2.getTemp(function (tOut) {
                //cl("Temp is "+tOut.toFixed(1)+" C");
                param.tOt =  parseFloat(tOut.toFixed(1));
                var gOt = GetHue;
                param.hOt = gOt(pinHumOt, tOut);

                if (callback) {
                    IsFan();
                }
            });
        });

        return;
    }


    /************************ Calculate ABS Humi ***************************/

    function CalcAbsH(t, h) { // t - temperature celsius, h - humidity %
        var tmp;
        var absHumid;
        tmp = Math.pow(2.718281828,(17.67*t)/(t+243.5));
        absHumid = (6.112*tmp*h*2.1674)/(273.15+t);
        //cl('Abs Humidity is ', absHumid.toFixed(2), "g/m3");
        return absHumid;
    }


    function IsFan(){

        var aHumIn  = CalcAbsH(param.tIn, param.hIn);
        var aHumOut = CalcAbsH(param.tOt, param.hOt);
        var delta = aHumIn - aHumOut;
        //cl("Delta = ", delta.toFixed(1));

        //if(((param.tIn < minInTemp) || (param.tOt > maxOutTemp)) && (param.fan === "ON")){
        if(((param.tIn < minInTemp) || (param.tOt >param.tIn)) && (param.fan === "ON")){
            SwitchFan(0);
            param.mod = "ON";
            param.faF = "OFF";
        }
        else if (param.mod == "ON") {
            if ((param.tIn >  param.tg) && (param.tIn > param.tOt)) {
                if ((delta > lagOn) && (param.fan === "OFF")) {
                    SwitchFan(1);
                }
                if  ((delta < lagOff) && (param.fan === "ON")) {
                    SwitchFan(0);
                }
            }
        }
        printLCD(aHumIn, aHumOut);
        // SlowSendData();
    }

    /*
    function SetRandom() {
        param.tIn = Math.random() * 10;        // Temperature at Cellar
        param.hIn = Math.random() * 100;        // Humidity at Cellar
        param.tOt = Math.random() * 10;        // Outside Temperature
        param.hOt = Math.random() * 20;
        IsFan();
    }
    */



    E.on('init', function() {
        setTimeout(function () {
            printLCD(1,1,true);
            GetSensors();
        }, 3000);

      var ddd = setInterval(function() {
        //SetRandom();
        GetSensors(true);
      }, makeDes*1000);

    });

    В итоге, все общается между собой следующим образом:
    cellar4.jpg
     
    Последнее редактирование: 5 окт 2016
    alp69 нравится это.
  18. ИгорьК

    ИгорьК Гуру

    40.2. Вентиляция погреба.
    OpenHab: создаем итемы.
    Код (Java):
    Group CellarN "Погреб" <pogreb>
    Group CellarNT "Температура" <pogreb> (CellarN)
    Group CellarNH "Влажность" <pogreb> (CellarN)

    String    cellarAll { mqtt="<[mosquitto:master433/state:state:default]" }
    String    cellarTIn    "Температура погреб [%s °C]"    <temperature> (CellarN, CellarNT)
    Number    cellarHIn    "Влажность погреб [%.1f %%]"    <weather_humidity> (CellarN, CellarNH )
    String    cellarTOut    "Температура на улице[%s °C]"    <temperature> (CellarN, CellarNT)
    String    cellarHOut    "Влажность на улице [%s %%]"    <weather_humidity> (CellarN, CellarNH )
    Switch    cellarFn        "Вентилятор"         (CellarN)
    Switch    cellarWk        "Режим"             (CellarN) { mqtt=">[mosquitto:master433/command:command:on:MAP(cellar.map)],>[mosquitto:master433/command:command:off:MAP(cellar.map)]" }
    Switch    cellarFF        "Принудительно"        (CellarN) { mqtt=">[mosquitto:master433/command:command:on:MAP(cellarfaf.map)],>[mosquitto:master433/command:command:off:MAP(cellarfaf.map)]" }
    String    cellarTt        "Цель [%s °C]"    <temperature> (CellarN) { mqtt=">[mosquitto:master433/command:command:*:default]" }
    Number    cellarSetTg        "Целевая Температура %d"
     
    Вставляем в сайтмэп:
    Код (Java):
    Group item=CellarN label="Погреб" {
            Text item=cellarTIn label="Температура в погребе [%s °C]" {
                Frame  {
                    Chart item=cellarTIn period=D
                    Chart item=CellarNT period=D
                }          
            }
            Text item=cellarHIn label="Влажность в погребе [%s %%]" {
                Frame  {
                    Chart item=cellarHIn period=D
                    Chart item=CellarNH period=D
                }          
            }

            Text item=cellarTOut label="Температура на улице [%s °C]" {
                Frame  {
                    Chart item=cellarTOut period=D
                    Chart item=CellarNT period=D
                }          
            }

            Text item=cellarHOut label="Влажность на улице [%s %%]" {
                Frame  {
                    Chart item=cellarHOut period=D
                    Chart item=CellarNH period=D
                }          
            }

            Switch item=cellarFn
            Switch item=cellarWk
            Switch item=cellarFF
            // Text item=cellarTt - здесь все правильно, этот итем не нужен на сайтмэп
            Setpoint item=cellarSetTg label="Цель [%d °C]" icon="target" minValue=0 maxValue=9 step=1
            }
        }
     
    Без правил - не обойтись. И не забудьте, пожалуйста, инициализировать итем cellarSetTg при старте системы какой-нибуль цифрой, например 4. По ходу дела, с первым же отчетом устройства целевая температура в погребе установится в соответствии с тем, что в устройстве.
    Код (Java):
    rule "Mqtt Cellar Decript"
      when
        Item cellarAll received update
      then
        var String json = (cellarAll.state as StringType).toString
        // {"unt":"cel","mod":"ON","fan":"OFF","faF":"OFF","tg":2,"tIn":11.1,"hIn":100.3,"tOt":12.8,"hOt":63.6}
        var String unit = transform("JSONPATH", "$.unt", json)
        if (unit == "cel") {
            var String tIn = transform("JSONPATH", "$.tIn", json)
            var String hIn = transform("JSONPATH", "$.hIn", json)
            var String tOt = transform("JSONPATH", "$.tOt", json)
            var String hOt = transform("JSONPATH", "$.hOt", json)
            var String fn = transform("JSONPATH", "$.fan", json)
            var String wk = transform("JSONPATH", "$.mod", json)
            var String ff = transform("JSONPATH", "$.faF", json)
            var String tg = transform("JSONPATH", "$.tg", json)

            postUpdate(cellarWk,wk)
            postUpdate(cellarFn,fn)
            postUpdate(cellarFF,ff)
            postUpdate(cellarTt,tg)
            postUpdate(cellarTIn,tIn)
            postUpdate(cellarHIn,hIn)
            postUpdate(cellarTOut,tOt)
            postUpdate(cellarHOut,hOt)
            postUpdate(cellarSetTg,tg)
        }
    end

    var Timer timerSetCellarTg = null
    rule "Set Cellar Targer Temperature"
    when
            Item cellarSetTg changed
    then
            if (timerSetCellarTg != null)
              timerSetCellarTg.cancel()
              timerSetCellarTg = createTimer(now.plusSeconds(2)) [|
              {
                var String setTg = '{"cel":1,"tg":'
                setTg = setTg + cellarSetTg.state.toString + '}'
                sendCommand(cellarTt, setTg)
                postUpdate(cellarTt, cellarSetTg.state.toString)
              }
            ]
    end
    А еще, в папочку /usr/share/openhab/configurations/transform надо положить два файла, которые в архиве прилагаются к этому сообщению.
    99321.jpg
    И на закуску - огурчик, с названием pogreb.png :)
    pogreb.png
     

    Вложения:

    • transform.zip
      Размер файла:
      386 байт
      Просмотров:
      210
    Последнее редактирование: 5 окт 2016
    alp69 нравится это.
  19. alp69

    alp69 Форумчанин

    Вентилятор, режим и принудительно - это все относится к вентилятору? Или "режим" это обогреватель? Или что-то из этого не управление, а индикация?
     
  20. ИгорьК

    ИгорьК Гуру

    Drawing1.jpg

    Первый свитч - индикация. Потом можно красивее сделать.
     
    alp69 нравится это.