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

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

  1. alp69

    alp69 Форумчанин

    Создайте в sitemap элемент chart. Назначьте ему итем, который меряет температуру (например). У итема должен быть прописан persistens - как ему себя вести и с какой базой данных общаться с какой периодичностью.
    Если Вы хотите в одном графике значения от разных итемов видеть - создайте групповой итем (нужным итемам назначьте эту группу) и его в сайтмепе прикрутите с созданному chart'у.
    Более подробно с картинками пока ответить не могу - с телефона пишу.
    db4o много места занимает. Лучше rrd4j.
     
  2. KiVor

    KiVor Нерд

    Спасибо огромное! С группами еще не работал. Попробую разобраться, об итогах отпишусь!
     
  3. alp69

    alp69 Форумчанин

    Эти значения задают максимум и минимум по ординате. То есть, если минимум установить 10, а максимум 15, то значения 5 или 15.5 будут за пределами области отображения графика.
    Другими словами - ордината перестает масштабироваться.
     
    Последнее редактирование: 8 мар 2016
  4. KiVor

    KiVor Нерд

    Попробовал сделать, вроде получилось, но пока не полностью. График давления рисуется. Все ок. Правда пока не понял как в Chart'е задавать деления на шкале времени (ось х). А то у меня там сутки и все. Хотелось бы неделю...
    А вот с датчиком температуры какой-то косяк. Значения в шкале не цифирные, а типа "20Е2,5"; "21Е1,8" и т.д. От куда он это берет? В mqtt отправляются нормальные значение, и в text item нормальные показания, а в графике хрень какая-то....
    Хотя с датчиком давления тоже не все гладко. У меня показания передаются с одним знаком после запятой, а в базу данных пишутся значения с 7 знаками после запятой. И в графике на "оси y" деления с двумя знаками после запятой. То же вопрос, откуда он берет остальные числа?
    Мы не об этих максимумах и минимумах.
    А вот об этих.
     
    Последнее редактирование: 10 мар 2016
  5. ИгорьК

    ИгорьК Гуру

    Могу предположить, что термометр ваш периодически выкидывает какие-то ошибочные большие значения. Такое бывает, когда слишком большой разброс значений входит в график.
     
  6. KiVor

    KiVor Нерд

    Хм... Не, тут что-то другое. Вечером почистил RRD4J. Посмотрел утром лог mqtt, все гладко, данные стабильные (24,1-24,8) за ночь. Ни единого пропуска или неадекватных значений.
    Самое странное что лог mqtt датчика давления тоже гладкий (753,2-755,5) за ночь и тоже ни единого пропуска или еще что.
    А в таблице RRD4J значения (753,195466874-755,522154686) и в таком духе.
    Может конечно сам датчик и снимает показания с такой точностью, но openhab общается с брокером mqtt. Там то таких цифр нет, я их отфильтровал еще на этапе arduino.
    Есть у кого мысли? Может я передаю цифры в какой-то не той кодировки с arduin'ки? Прошу прощения за свой русский...

    Вот что в mqtt. Данные передаются четко, без сбоев, с одним знаком после запятой. Лог смотрел, тоже ни нулей, не бешеных значений:
    [​IMG]
    Вот что в OpenHab. Значения четкие, обновляются, также все отлично:
    [​IMG]
    А вот что мы видим в db rrd4j датчика давления. Откуда-то взялось еще куча цифр после запятой:
    [​IMG]
    Вот что мы видим там же, но датчика температуры (кстати это один и тот же датчик). Вообще ахинея полная:
    [​IMG]
    Вот так выглядит chart температуры:
    [​IMG]
    Chart давления выглядит нормально.

    Вот кусочек кода считывания данных с датчиков и передачи в openHab:
    Код (C++):
      {
      // Получение данных с датчиков с заданным интервалом
      if (millis() > (time1 + 10000))
      {
        if (!client.connected())
        {
          if (client.connect("myhome")) client.subscribe("/myhome/in/#");
        }
        if (client.connected())
        {
          // BMP180
          dps.calcTrueTemperature();                      // получить даные с датчика
          dps.getTemperature(&temperature00);             // присвоитьб температуре переменную
          dps.getPressure(&pressure);                     // присвоить давлению переменную
          dtostrf(temperature00/10.0, -1, 1, msgT00);     // привести к нужному формату
          dtostrf(pressure/133.3, -1, 1, msgD0);          // и конвертировать

          // DHT22
          float temperature0 = dht0.getTemperature();
          float humidity0 = dht0.getHumidity();
          float temperature1 = dht1.getTemperature();
          float humidity1 = dht1.getHumidity();
          float temperature2 = dht2.getTemperature();
          float humidity2 = dht2.getHumidity();
          float temperature3 = dht3.getTemperature();
          float humidity3 = dht3.getHumidity();
          dtostrf(temperature0, -2, 1, msgT0);
          dtostrf(humidity0, -2, 1, msgH0);
          dtostrf(temperature1, -2, 1, msgT1);
          dtostrf(humidity1, -2, 1, msgH1);
          dtostrf(temperature2, -2, 1, msgT2);
          dtostrf(humidity2, -2, 1, msgH2);
          dtostrf(temperature3, -2, 1, msgT3);
          dtostrf(humidity3, -2, 1, msgH3);

          // Передаем на mqtt broker
          client.publish("/myhome/out/T00",(msgT00));
          client.publish("/myhome/out/D0",(msgD0));
          client.publish("/myhome/out/T0",msgT0);
          client.publish("/myhome/out/H0",msgH0);
          client.publish("/myhome/out/T1",msgT1);
          client.publish("/myhome/out/H1",msgH1);
          client.publish("/myhome/out/T2",msgT2);
          client.publish("/myhome/out/H2",msgH2);
          client.publish("/myhome/out/T3",msgT3);
          client.publish("/myhome/out/H3",msgH3);
    }
      }
        time1 = millis();
    }
     
    Последнее редактирование: 11 мар 2016
    Securbond нравится это.
  7. KiVor

    KiVor Нерд

    Кстати, по пути попыток выяснить причину моей проблемы, я таки с min и max разобрался. А вот со своей проблемой стою на месте...
     
    ИгорьК нравится это.
  8. Securbond

    Securbond Гуру

    Стало интересно, посмотрел у себя
    graf1.PNG
    иногда то же проскакивает что то странное.
     
  9. ИгорьК

    ИгорьК Гуру

    Вот где может быть решение!
    RRD4J усредняет значения, если они приходят чаще чем раз в минуту.
    Проверьте, чтобы информация приходила реже и, значит, не усреднялась.
    Попробуйте поиграть временем интервалов.
     
  10. KiVor

    KiVor Нерд

    Интересно... У меня данные приходят намного чаще чем раз в минуту. Можно ли, к примеру, оставить сообщения mqtt чаще, а в настройках RRD4J поставить everyMinute?
    Попробую сейчас...
     
  11. KiVor

    KiVor Нерд

    Разгадка в настройках db в файле openhab.cfg
    Код (C++):
    #rrd4j:<defname>.def=[ABSOLUTE|COUNTER|DERIVE|GAUGE],<heartbeat>,[<min>|U],[<max>|U],<step>
    #rrd4j:<defname>.archives=[AVERAGE|MIN|MAX|LAST|FIRST|TOTAL],<xff>,<steps>,<rows>
    #rrd4j:<defname>.items=<list of items for this defname>
    Если там ничего не писать, то будут настройки по умолчанию со средними значениями. Я туда скопировал настройки из примера и особо не вдумывался в смысл строк. Вчера покопался и нашел где была ошибка. AVARAGE это и есть среднее значение. И можно сделать так, чтоб средних значений не было, с приходом данных хоть каждую секунду.
    Спасибо, что разрешили пофлудить в вашей теме!
     
    Последнее редактирование: 13 мар 2016
    Egony нравится это.
  12. Securbond

    Securbond Гуру

    Может быть немного не в тему ....
    необходимо передавать данные с Arduino на openhab через шилд W5100.
    простой скетч работает, отправляет статические данные в брокер, а вот с переменными никак не выходит.
    может завалялся у кого пример как переменные засовывать в client.publish("test","privet");
    Статический "privet" уходит норм, а вот так client.publish("test",t); (t - переменная меняется от 0-150 в цикле for).
    Начинает материться на переменную. Догадываюсь что проблема в формате передаваемых данных, а как решить ??????
    Код (C++):

    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>
    char t = 0;
    // Update these with values suitable for your network.
    byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
    IPAddress ip(192, 168, 0, 15);
    IPAddress server(192, 168, 0, 100);

    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
      for (int i=0;i<length;i++) {
        Serial.print((char)payload[i]);
      }
      Serial.println();
    }

    EthernetClient ethClient;
    PubSubClient client(ethClient);

    void reconnect() {
      // Loop until we're reconnected
      while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("arduinoClient")) {
          Serial.println("connected");
        }
            else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          delay(5000);
        }
      }
    }
    void setup()
    {
      Serial.begin(9600);

      client.setServer(server, 1883);
      client.setCallback(callback);

      Ethernet.begin(mac, ip);
      // Allow the hardware to sort itself out
      delay(1500);
    }

    void loop()
    {
      if (!client.connected()) {
        reconnect();
      }
    for ( t = 150; t >= 0; t--){    
           // Once connected, publish an announcement...
          client.publish("test",t);
           }
       }  
    }
     
  13. ИгорьК

    ИгорьК Гуру

    Превращайте переменную в String:
    String toSend = (String) peremennaja;
    Отправляйте toSend.
    Или так:
    client.publish("test",(String)t);
     
  14. Securbond

    Securbond Гуру

    Код (C++):
    void loop()
    {
      if (!client.connected()) {
        reconnect();
      }
    for ( t = 150; t >= 0; t--){    
           // Once connected, publish an announcement...
           String toSend = (String) t;
           client.publish("test",toSend);
           }
       
    }
    ошибка - no matching function for call to 'PubSubClient::publish(const char [5], String&)'

    Что бы тут не флудить создал тему http://forum.amperka.ru/threads/ardino-w5100-mqtt-openhab.7749/
     
    Последнее редактирование: 13 мар 2016
  15. ИгорьК

    ИгорьК Гуру

    Тогда отправляйте &toSend.
     
  16. Securbond

    Securbond Гуру

    Код (C++):
    mqtt_basic1.ino: In function 'void loop()':
    mqtt_basic1:60: error: no matching function for call to 'PubSubClient::publish(const char [5], String*)'
    mqtt_basic1.ino:60:37: note: candidates are:
    In file included from mqtt_basic1.ino:4:0:
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:130:12: note: boolean PubSubClient::publish(const char*, const char*)
        boolean publish(const char* topic, const char* payload);
                ^
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:130:12: note:   no known conversion for argument 2 from 'String*' to 'const char*'
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:131:12: note: boolean PubSubClient::publish(const char*, const char*, boolean)
        boolean publish(const char* topic, const char* payload, boolean retained);
                ^
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:131:12: note:   candidate expects 3 arguments, 2 provided
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:132:12: note: boolean PubSubClient::publish(const char*, const uint8_t*, unsigned int)
        boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
                ^
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:132:12: note:   candidate expects 3 arguments, 2 provided
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:133:12: note: boolean PubSubClient::publish(const char*, const uint8_t*, unsigned int, boolean)
        boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
                ^
    D:\Arduino\libraries\PubSubClient\src/PubSubClient.h:133:12: note:   candidate expects 4 arguments, 2 provided
    no matching function for call to 'PubSubClient::publish(const char [5], String*)'
    Легче не стало((
     
  17. ИгорьК

    ИгорьК Гуру

    Последний вариант идём в гугл по названию функции и внимательно смотрим код, который находится. Не может быть чтобы переменные не отправлялись :)
     
  18. Securbond

    Securbond Гуру

    Решено! Нашел рабочий код.

    Код (C++):

    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>
    char t = 0;
    // Update these with values suitable for your network.
    byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
    IPAddress ip(192, 168, 0, 15);
    IPAddress server(192, 168, 0, 100);
    int sensorPin=5;
    int lastTemperature;
    unsigned long lastTime;
    char buffer[10];

    void callback(char* topic, byte* payload, unsigned int length) {
      // handle message arrived (no messages expected though)
    }

    EthernetClient ethClient;
    PubSubClient client(server, 1883, callback, ethClient);

    void setup() {
      Ethernet.begin(mac, ip);
      if (client.connect("arduinoClient")) {
        client.publish("test/status/arduino01","online");
        lastTemperature=0;
        lastTime=0;
      }
    }

    void loop() {
      int reading=analogRead(sensorPin);
      int temperature = ((reading * 0.004882)-0.50)*100;
      if(temperature!=lastTemperature) {
        if(millis()>(lastTime+1000)) {
          sprintf(buffer,"%d",temperature);
          client.publish("test/device/arduino01",buffer);
          lastTemperature=temperature;
          lastTime=millis();
        }
      }
      client.loop();
    }
     
    ИгорьК нравится это.
  19. KiVor

    KiVor Нерд

    Если отправлять как String, не будет работать persistence. По крайней мере у меня не работало...
    В свое время тоже пытался разобраться с sprintf, но так и не получилось с ней нормально подружиться.
    Посмотрите мой пост #469. Я привожу кусок кода, где происходит считывание с 5 датчиков, преобразование к нужному формату с перестановкой запятой, конвертация sprintf dtostrf и отправка по mqtt.
    [​IMG]
     
    Последнее редактирование: 13 мар 2016
    ИгорьК и Securbond нравится это.
  20. KiVor

    KiVor Нерд

    Посоветовал бы отвыкнуть от функции delay. Она очень паразитная.
    Пока еще не проверял, но по идеи должно быть ок. В Москве сейчас проблематично найти "-" :D