NEWS

Интеграция Arduino по сети Ethernet в ioBroker через адаптер simple-api


  • Привет всем.

    Можно интегрировать контроллер на базе платформы Arduino в ioBroker с помощью MQTT и адаптера Node-red…

    Если эти варианты вас не устраивают, читаем дальше))

    В составе ioBroker имеется драйвер https://github.com/ioBroker/ioBroker.simple-api, с его помощью можно получить информацию о состоянии оборудования/переменных сервера и даже управлять, передавать данные.

    Для примера приведу описание системы: имеется контроллер Arduino (UNO/Mega/etc) с шилдом ethernet.

    На цифровой pin-9 подключена кнопка с программной подтяжкой к +5В. На цифровой pin-8 реле или другой механизм.

    Нажатием кнопки (при переходе 1->0) в программе изменяется состояние реле на противоположное. Нажали один раз - свет включился, нажали еще раз - выключился, еще раз - включился и т.д.

    Так же состоянием реле можно управлять из визуализации (адаптер VIS) где отображается состояние и реле и кнопки.

    На сервере крутится скрипт, который создает переменные кнопки и реле. При нажатии кнопки на ардуине, контроллер отправляет новое состояние в ioBrooker GET-запросом.

    Если состояние реле поменялось по нажатию кнопки, ардуина так же отправляет GET-запрос. Если в VIS-адаптере переключили состояние реле, то скрипт, подписанный на изменение переменной только из VIS, отправляет GET-запрос на ардуину и состояние реле меняется.

    Надеюсь не слишком сложно объяснил))

    Прошу протестировать…
    50_test02.zip


  • Но зачем если есть mqtt? В чем преимущество?


  • @instalator:

    Но зачем если есть mqtt? В чем преимущество? `
    У меня возникли проблемы с отправкой большого объема данных в короткое время, ардуина начинала отваливаться и при этом данные терялись. При этом система очень динамична и потерянные данные уже через пару секунд могли оказаться не актуальными.

    Во-вторых, MQTT подразумевает постоянное соединение, HTTP - отправил и забыл…

    В третьих, у меня нет навыков/знаний чтобы искать глюки и разбираться в коде библиотек для ардуины и адаптера MQTT для ioBroker. HTTP в этом плане гораздо проще))

    ИМХО.

    Плюс к тому, не хотел бы чтобы пользователи смотрели на эту реализацию как "почему не MQTT?" - лучше как "О_о, нормальная альтернатива, запасной вариант, надо потренироваться и т.д."


  • @electric69:

    @instalator:

    Но зачем если есть mqtt? В чем преимущество? `
    У меня возникли проблемы с отправкой большого объема данных в короткое время, ардуина начинала отваливаться и при этом данные терялись. При этом система очень динамична и потерянные данные уже через пару секунд могли оказаться не актуальными.

    Во-вторых, MQTT подразумевает постоянное соединение, HTTP - отправил и забыл…

    В третьих, у меня нет навыков/знаний чтобы искать глюки и разбираться в коде библиотек для ардуины и адаптера MQTT для ioBroker. HTTP в этом плане гораздо проще))

    ИМХО.

    Плюс к тому, не хотел бы чтобы пользователи смотрели на эту реализацию как "почему не MQTT?" - лучше как "О_о, нормальная альтернатива, запасной вариант, надо потренироваться и т.д." `
    Если мне память не изменяет в протоколе MQTT есть уровень важности (QoS). Надо почитать про MQTT, у меня небыло такой цели поэтому не заморачивался.

    BlueFox драйвер MQTT поддерживает QoS?


  • Доброго времени суток. Судя по дате последнего сообщения эта тема никого не заинтересовала. Ну а мне хотелось-бы разобраться как осуществить предложенное в первом сообщении.

    В общем есть сабж http://majordomo.smartliving.ru/forum/v … 53f1cd99ba

    Работает без нареканий уже давно и необходимости на что то менять не вижу. Никакого mqtt в нем нет, обычные get запросы http.

    В мажордоме это работало хорошо. Но пришло время перехода на ioBroker. Так вот немного поковырявшись я научился ним управлять.

    Но как организовать обратную связь от устройства пока не пойму. Чувствую что надо через адаптер simple-api но как именно это сделать не соображу. Может кто подскажет какой скрипт нужен. Апи устройства прилагаю ниже.

    ! Протокол взаимодействия по HTTP
    ! Получение состояния реле
    ! HTTP-GET запрос вида
    ! http://megalight/state?c=get&n=1
    ! n - ID нужного реле (обязательный)
    ! Ответ: text/plain в виде
    ! 1;255
    ! где первое число - состояние (1 - вкл), второе - значение диммера
    ! Установка состояния реле
    ! HTTP-GET запрос вида
    ! http://megalight/state?c=set&n=1&o=1&v=200&t=30000
    ! http://megalight/state?c=set&n=1&i=10
    ! n - ID нужного реле (обязательный)
    ! o - состояние (1 - вкл, 0 - выкл)
    ! v - значение диммера (0-255)
    ! i - инкремент/декремент значения диммера (-255 по 255)
    ! t - таймаут в миллисекундах
    ! Ответ: пусто
    ! Получение состояния кнопки
    ! HTTP-GET запрос вида
    ! http://megalight/state?c=button&n=1
    ! n - ID нужной кнопки/выключателя (обязательный)
    ! Ответ: text/plain в виде
    ! 1
    ! состояние (1 - нажата, 0 - не нажата)

    ps. Я тут уточнил. Девайс сам отправляет get на сервер при изменении состояния выходов. Так вот как мне послушать этот ответ и сопоставить с моей переменной?

    Сейчас управление работает на вот таком скрипте:

    var url = 'http://192.168.0.89';
    var request = require('request');
    var options = {
            	url: ''
            };
    on({id: 'javascript.0.test', change: 'any'}, function (obj) {
        if(obj.newState.val === 0){
    	options.url = url+'/state?c=set&n=7&o=1';
        } else {
        	options.url = url+'/state?c=set&n=7&o=0';
        }
        request(options, function (error, response, body) {
            log('Ответ' + body);
        });
    });
    
    

    И такой скрипт проверял тоже работает:

    on({id: 'javascript.0.Arduino1.DO', change: 'any'}, function (obj) {
        if((obj.newState.from == 'web.0' || obj.newState.from == 'system.adapter.web.0' ) && obj.newState.val == '0'){
            request ('http://192.168.0.89/state?c=set&n=7&o=0');
        }
        if((obj.newState.from == 'web.0' || obj.newState.from == 'system.adapter.web.0' ) && obj.newState.val == '1'){
            request ('http://192.168.0.89/state?c=set&n=7&o=1');
        }
    });
    

    Чувствую что в эти скрипты надо что-то добавить, но вот что?


  • Добрый день. Апну темку. Вдруг поможет. Я сам пока не справился.


  • мегалайт нужно перешивать, ибо у simpleAPIдругой формат команд

    либо поднимать сервер на скрипте


  • Ух ну тут я совсем не программист.

    То есть Вы хотите сказать что без кардинальных вмешательств не получится полноценно подружить железку с сервером?

    Или это можно сделать как то по другому?


  • Чисто скриптом делать

    как-то так:

    var http = require('http');
    var server = http.createServer().listen(8091); // на каком порту слушаем?
    
    server.on('request', function (req, res) {
        res.writeHead(200);
        if (req.method == 'POST') { // или GET?
            var body = '';
        }
    
        req.on('data', function (data) {
            body += data;
            console.log(body);
        });
    
        req.on('end', function () {
    
        });
    
    });
    
    

    …и парсить полученную переменную

    вопрос чисто программерский


  • @Pooh:

    Чисто скриптом делать

    как-то так: `
    Спасибо за пинок в нужном направлении.

    Итого инструкция получилась такая:

    • 1. В скетче MegaLight указываем порт по которому контроллер будет отправлять запросы на сервер.
    В итоге он слушает команды на стандартном 80-м порту а отправляет на том который укажем. 
    
    • 2. Создаём папку в модуле JavaScript с понятным именем (например MegaLight1).
    • 3. В этой папке создаём скрипт для каждого канала реле. Обозвать можно как угодно чтоб понятно было к какому каналу он имеет отношение.
    createState('MegaLight1.lightcenter', '');
    on({id: 'javascript.0.MegaLight1.lightcenter', change: 'any'}, function (obj) {
        if((obj.newState.from == 'web.0' || obj.newState.from == 'system.adapter.web.0' ) && obj.newState.val == '0'){
            request ('http://192.168.120.25/state?c=set&n=3&o=0');
        }
        if((obj.newState.from == 'web.0' || obj.newState.from == 'system.adapter.web.0' ) && obj.newState.val == '1'){
            request ('http://192.168.120.25/state?c=set&n=3&o=1');
        }
    });
    
    • 4. Там же создаём ещё один скрипт для получения обратной связи от контроллера.
    var http = require('http');
    var server = http.createServer().listen(8083); // на каком порту слушаем?
    server.on('request', function(req, res) {
         res.writeHead(200);
         var getback = req.url;
         var vars = getback.split("&"); 
            for (var i=0;i<vars.length;i++) { 
               var pair = vars[i].split("="); 
            }
            if (vars[4] == 'on=1') {
                var state = 1;
                 } else {
                var state = 0;
                 }
         if (vars[3] == 'id=1') {
             setState ('javascript.0.MegaLight1.braright', state);
           } else if (vars[3] == 'id=2') {
             setState ('javascript.0.MegaLight1.braleft', state);
           } else if (vars[3] == 'id=3') {
             setState ('javascript.0.MegaLight1.lightcenter', state);
           } else if (vars[3] == 'id=4') {
             setState ('javascript.0.MegaLight1.lightdop', state);
           }
    log('Канал ' + vars[3] + ' Состояние-' +state)        
    });

  • Участник @rw6miu написал в Интеграция Arduino по сети Ethernet в ioBroker через адаптер simple-api:

    • 3. В этой папке создаём скрипт для каждого канала реле.
    • 4. Там же создаём ещё один скрипт

    Можно все реле/каналы и сервера в одном скрипте описать...


  • Участник @Pooh написал
    Можно все реле/каналы и сервера в одном скрипте описать...

    Можно конечно, но тогда чуток сложнее отлаживать и отслеживать работу скриптов. Исчезает возможность оперативно отключать их.
    У меня сейчас другая проблема вылезла. Старая система благополучно умерла и была полностью переустановлена без возможности восстановления всего включая скрипты. Сейчас собираю обратно всё по крупицам. В итоге раньше у меня работали эти скрипты а теперь первый из них не работает. Причём если я из строки

    if((obj.newState.from == 'web.0' || obj.newState.from == 'system.adapter.web.0' ) && obj.newState.val == '0'){
    

    выкидываю упоминание о web драйвере и оставляю

    if(obj.newState.val == '0'){
    

    то скрипт начинает работать но происходит какая-то обратная связь со вторым скриптом и из за этого хаотичное включение и выключение света с очень быстрой скоростью.
    Не пойму в чём проблема. Может в каких то настройках драйвера web.0. Раньше ведь всё работало.

Suggested Topics

  • 10
  • 17
  • 2
  • 13
  • 1
  • 15
  • 3
  • 5

1.7k
Online

37.0k
Users

42.7k
Topics

593.3k
Posts