Умный дом: Domoticz.

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

Метки:
  1. ИгорьК

    ИгорьК Победитель модулей

    Вещь интересная. Но я не обнаружил там форума. Это говорит не в пользу.
     
  2. ИгорьК

    ИгорьК Победитель модулей

    О непонятном.
    Domoticz имеет встроенный модуль JSON.
    Работать с ним очень просто. Пример скрипта DzVent:
    Код (Lua):
    -- Примеры отправки на Domoticz
    -- {"idx":62,"nvalue":0,"svalue":"{\"unt\":\"cel\",\"mod\":\"On\",\"tmp\":\"32.34\",\"hIn\":\"47\"}"}
    return {
        -- скрипт активен
        active = true,
        -- если получено что-то на idx 62
        on = {
            devices = {
                62,
            },
        },
        execute = function(domoticz, device)
            -- Загружаем модуль JSON
            local json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
            -- Добываем данные из idx 62, он же Текст 'Подвал Инфо'
            local myjson = domoticz.devices('Подвал Инфо').state
       
            -- Модуль преобразует данные в объект 'myjson'
            local myjdecod  = json:decode(myjson)
           
            -- И запрашиваем у него отдельные элементы
            local myunt = myjdecod.unt or "no Unit"
            local mymod = myjdecod.mod or "no Mod"
            local mytmp = myjdecod.tIn or 85
            local myhum = myjdecod.hIn or 75
           
            -- Дальше обработка...
            -- ...
        end
    }
    Все отлично работает. Но ровно до тех пор, пока в JSON меньше шести пар. А дальше:

    upload_2017-10-9_16-3-45.png

    Печаль.
     
  3. ИгорьК

    ИгорьК Победитель модулей

    Присутствие в сети и управление выключателями.
    Shell скрипт.
    Источник находится здесь. Переделал код под любое количество наблюдаемых железок.
    Код (Bash):
    #!/bin/bash
    loop=1
    sleep=10
    switchI=61 # idx Igor Switch
    switchM=64 # idx Marina Switch
    mphone=192.168.0.214 # Marina Phone
    iphone=192.168.0.107 # Igor Phone
    echo Phone on = 0, Phone off = 1

    while [ "$loop" -eq "1" ]
    do
        function workswitch {
            echo ""
            echo ""
            nmap -sn $1 | grep -q latency
            phone1=$?
            echo Phone $3 = $phone1
       
            if [ "$phone1" -eq "1" ];
            then
                echo No $3 phone, Checking status switch $2;
                curl -s "http://127.0.0.1:8090/json.htm?type=devices&rid="$2"" | grep '"Status" : "Off",'
                switchon=$?
                if [ "$switchon" -eq "0" ];
                    then
                         echo Switch $2 is already OFF, skipping sending command to Domoticz;
                    else
                         echo Switch $2 was ON, turning switch OFF; curl "http://127.0.0.1:8090/json.htm?type=command&param=switchlight&idx="$2"&switchcmd=Off";
                fi
            else
                 echo Got $3 phone, Checking status switch $2;
                 curl -s "http://127.0.0.1:8090/json.htm?type=devices&rid="$2"" | grep '"Status" : "On",'
                 switchon=$?
                 if [ "$switchon" -eq "0" ];
                     then
                         echo Switch $2 is already ON, skipping sending command to Domoticz;
                     else
                         echo Switch $2 was OFF, turning switch ON; curl "http://127.0.0.1:8090/json.htm?type=command&param=switchlight&idx="$2"&switchcmd=On";
                 fi
            fi
            echo ""
            echo ""
        }

        workswitch $mphone $switchM Marina
        workswitch $iphone $switchI Igor
        echo ""
        echo ""
        echo "Execution done, sleeping for $sleep seconds"
        sleep $sleep
    done
     
    Последнее редактирование: 13 окт 2017
    petr0vsk и SergeiL нравится это.
  4. ИгорьК

    ИгорьК Победитель модулей

    DHT-22, однако.
    Очень простой скрипт, железка из старых запасов. Железка абсолютное дерьмо, но для контроля чего-то холодно/горячо сгодится (дублирующий датчик температуры в бойлерной).

    1. Делаем тупое железо "Dacha Temperature"
    upload_2017-10-16_15-49-6.png


    2. Создаем два Devica.

    2.1. DHT-22 как Temp+Hum

    upload_2017-10-16_15-52-48.png

    2.2. DHT-22 Live как Swich

    upload_2017-10-16_15-55-13.png

    3. Узнаем IDX этих элементов:

    upload_2017-10-16_15-57-20.png


    4. Заливаем в ESP-8266 такой скрипт:

    Код (Lua):
    unitIDX = 69
    dhtIDX = 68

    pin = 4
    broker="МОЙ.БРОКЕР.КОМ"
    port=1883
    myClient="dht_0021"
    name=myClient
    pass="Superpassword"
    m = mqtt.Client( myClient, 120, name, pass)
    -- Это сообщение о потере связи с железкой
    m:lwt('domoticz/in', '{"command":"switchlight","idx":'..unitIDX..',"switchcmd":"Off"}',0,0)
    publish = false

    m:on("offline", function(con)
        publish = false
        connecting()
    end)

    function connecting()
        local checktmr
        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)
                        -- Соединились с брокером - зажгли лампу в Домотикз
                        m:publish('domoticz/in', '{"command":"switchlight","idx":'..unitIDX..',"switchcmd":"On"}',0,0)
                        print("Connected")
                        publish = true
                        tmr.stop(checktmr)
                        tmr.unregister(checktmr)
                        checktmr = nil
                end)
            end
        end
        getConnect()
        checktmr = tmr.create()
        checktmr:alarm(15000, 1, getConnect)
    end

    function publish_data()
          if wifi.sta.status() == 5 then
             local status,temp,humi = dht.readxx(pin)
             print(status,temp,humi)
            if (status == 0) then
                print("Status OK, publishing data.")
                if publish then
                    -- Публикуем данные на железку
                    m:publish("domoticz/in",'{"idx":'..dhtIDX..',"nvalue":0,"svalue":"'..temp..';'..math.floor(humi)..';0"}',0,0)
                end
            end
          end
    end

    tmr.create():alarm(60000, 1, publish_data )
    connecting()
    5. Идем в Roomplan:

    upload_2017-10-16_16-8-25.png


    Создаем комнату "Зал":

    upload_2017-10-16_16-14-51.png


    Собираем в "Зал":

    upload_2017-10-16_16-18-2.png


    Наблюдаем:

    upload_2017-10-16_16-18-49.png
     
    Последнее редактирование: 17 окт 2017 в 08:58
    petr0vsk нравится это.
  5. ИгорьК

    ИгорьК Победитель модулей

    Ну вот и я присоединился... Слишком много уже железа заточено под OpenHab. Сообщения Mqtt переписывать в них нет времени да и желания. Мои опыты излагаю ниже.

    0. Преобразуем одно сообщение MQTT в другое. Поэтому поток выглядит всегда так:

    upload_2017-10-20_14-37-17.png

    1. Передача от топика OpenHab температуры на Domoticz:

    upload_2017-10-20_14-41-43.png

    Настройка входного MQTT:

    upload_2017-10-20_14-38-55.png

    Настройка выходного MQTT:

    upload_2017-10-20_14-39-55.png

    А вот и функция, что превращает одни топики в другие:

    upload_2017-10-20_14-41-21.png


    И что же там написано в окошке на славном JavaScript?
    А вот что:
    Код (Javascript):
    var newmsg = {}
    var ss = '' +  msg.topic.substring(6);
    function setSwitch(idx, nm){
        var switchpayload = '{"command":"switchlight","idx":' + idx + ',"switchcmd":"'+ nm +'"}';
        return switchpayload;
    }
    function setTemp(idx, nm){
        var temppayload = '{"idx":' + idx +',"svalue":"' + nm + '"}';
        return temppayload;
    }
    function setHumi(idx, nm){
        nm = Math.round(nm);
        var humipayload = '{"idx":' + idx +',"nvalue":' + nm + ',"svalue":"0"}';
        return humipayload;
    }

    function setWind(idx, nm){
        nm = Math.round(nm * 10);
        var sv = '0;N;' + nm +';' + nm + '';
        var windpayload = '{"idx":' + idx +',"nvalue":0,"svalue":"' + sv +';0;0"}';
        return windpayload;
    }


    switch (ss) {
      case 'tbme':
        newmsg.payload = setTemp(41, msg.payload);
        return newmsg;
      case '280317EA0500000D':
        newmsg.payload = setTemp(42, msg.payload);
        return newmsg;
      case '28AFFED50400007C':
        newmsg.payload = setTemp(43, msg.payload);
        return newmsg;
      case '28B1AED5040000A1':
        newmsg.payload = setTemp(44, msg.payload);
        return newmsg;
      case 'humi':
        newmsg.payload = setHumi(45, msg.payload);
        return newmsg;
      case 'blr':
        var com = 'Off';
        if (msg.payload == 'ON') {
            com = 'On';
        }
        newmsg.payload = setSwitch(46, com);
        return newmsg;
      case 'pres':
        newmsg.payload = setTemp(48, msg.payload);
        return newmsg;
      case 'heap':
        newmsg.payload = setTemp(87, msg.payload);
        return newmsg;
      case 'switch':
        var com = 'Off';
        if (msg.payload == 'ON') {
            com = 'On';
        }
        newmsg.payload = setSwitch(50, com);
        return newmsg;
      case 'wind':
        newmsg.payload = setWind(51, msg.payload);
        return newmsg;
      default:
        return null;
    }
    return null;

    Сообщения для данного переработчика приходят в топиках типа "narod/..."
    Код удаляет "narod/" а с остатком работает через case/switch, формируя разные тела сообщений, в зависимости от того что пришло.
    Преобразуются сообщения типа:
    • выключатель;
    • температура;
    • влажность;
    • ветер;
    • все остальное.
     
    Последнее редактирование: 20 окт 2017 в 16:01