Перейти к публикации
iT4iT.CLUB

Рекомендованные сообщения

Доброе время суток.

02.11.2018 в 13:12, pasha413 сказал:

Здравствуйте. снова добрался до ESP-01, решил подключить BME280 к выводам 0 и 2, показаний нет, при сканировании датчик то появляется то пропадает. так же происходит и с другими датчиками i2c. в чем может быть проблема? DHT22 работал нормально

Давайте начнем с самого главного - DHT22 не работает с i2c шиной, для него требуется отдельный порт микроконтроллера, поэтому работа с ним НЕ может быть такой же, как работа с BME280. По моему субъективному мнению, их не стоит ставить на одном уровне, BME280 более выгодный и надежный вариант.

Теперь о проблеме, причин может быть несколько:

  1. Порт микроконтроллера уже используется чем-то
  2. Ошибка в коде
  3. Плохой контакт i2c шины с микроконтроллером
  4. Плохой контакт i2c шины с одним из датчиков
  5. Один из датчиков вносит хаос в работу всей шины

Меня очень настораживает перевод одного из стандартных портов i2c шины на другую "ногу" микроконтроллера, т.к это не даст совершенно ничего кроме физического переезда на другую группу контактов, но это было сделано, значит для чего то было нужно. Начните по порядку, возьмите оригинальную программу и оставьте только i2c шину с датчиками на оригинальных портах, проверьте работоспособность. Так станет ясно имеется ли проблема в самих датчиках или шине. Если проблема ушла, то пробуйте сменить порты шины (программно и аппаратно), если проблема не проявляется, то добавляйте поэтапно все используемые модули, сенсоры и т.п с поэтапным изменением в коде.

02.11.2018 в 16:46, Devilisimo сказал:

@Kitsum Прошу помощь советом. Данный код для опроса управления GPIO. При планомерной работе все хорошо. Если включить подряд несколько выходов, подать команду. Происходит срабатывание только последнего выхода в списке команд. Может чем-то поможете

Что явно бросается в глаза так это массовый вызов callswitch в callback с последующим присвоением ошибочных значений для переменных. Функция callback вызывается каждый раз, когда приходит сообщение и этот факт ставит нас в строгие рамки.

Например, пришло сообщение для субтопика switch0, что при этом произойдет? А произойдет следующее, всем переменным, кроме одной будет присвоено неопределенное логическое значение, возвращаемое функцией callswitch т.к проверки описанные в этой функции предусматривают совпадение только с одним топиком, в противном случае переменная sw остается явно не заданной, то есть нам вообще неизвестно её значение. Аналогичная ситуация должна прослеживаться в случае поступления в любой топик, на который оформлена подписка, значения отличного от тех, что участвуют в проверках. И также она будет воссоздана для всех топиков в случае если во время работы программы был удален конфигурационный параметр отвечающий за корневой топик.

Что сразу можно сказать по данному фрагменту кода

sw_on_0  = callswitch(top, msg,  0);
sw_on_12 = callswitch(top, msg, 12);
sw_on_13 = callswitch(top, msg, 13);
sw_on_14 = callswitch(top, msg, 14);
sw_on_15 = callswitch(top, msg, 15);

Он не допустим в функции callback, по крайней мере до тех пор, пока функция callswitch будет возвращать ошибочные значения во всех случаях кроме одного, это совпадение имени топика. Вообще я бы рекомендовал изменять за раз только одну переменную, ту к которой адресовано сообщение и улучшить проверки поступающих значений.

Позвольте дать Вам еще пару советов по поводу кода, это поможет не наступить на грабли в будущем.

Вы ввели дополнительную переменную, как я понимаю, для контроля наличия соединения.

/* вырезка из кода */
connect_OK = true;

К сожалению, я не увидел, когда происходит определение обрыва соединения и ее значение меняется на false. Взамен этой переменной воспользуйтесь уже готовым методом объекта mqttAPI

mqttAPI.connected()

Он возвращает логическое значение, соответствующее наличию или отсутствию соединения с MQTT брокером.

Вы можете оптимизировать описанную ниже конструкцию

//gpio 0 D3 нежелательно
if (sw_on_0 == true and digitalRead(0) == !gpio_enable)
{ digitalWrite(0, gpio_enable); mqttPublish("switch/on","gpio_0_is_ON"); }
else if (sw_on_0 == false and digitalRead(0) == gpio_enable) digitalWrite(0, !gpio_enable);

до такого вида

if (digitalRead(0) != sw_on_0) {
    digitalWrite(0, !digitalRead(0));
    mqttPublish("switch/on", sw_on_0 ? "gpio_0_is_ON" : "gpio_0_is_OFF");
}

Теперь о главном.

Я бы поставил под сомнение стоит ли использовать в функции callswitch ответ в виде вызова mqttPublish. На эту операцию тратится очень много времени, тем более, что ответ отправляется, когда планировщик задач вызывает функцию проверки соответствия состояния портов. Функция callswitch вызывается в функции callback, что не очень хорошо из-за описанной ситуации.

В функции callswitch объявлена переменная sw использующаяся с оператором return.

boolean sw;

Остается не ясным, что вернет функция callswitch в случае если конфигурационная переменная mqtt_path не была задана, по сути не указан корневой топик в web интерфейсе. Или поступило любое сообщение отличное от ON или OFF в различных регистровых вариациях, например, "BlaBlaBla". Переменная sw должна иметь определенное начальное значение или это значение должно явно определяться в ходе выполнения функции, особенно когда функция должна вернуть результат в случае несовпадения топиков и этот результат должен быть в различных ситуациях разный, как true так и false (опять отсылка к массовому вызову callswitch в callback).

В общем Ваша проблема кроется в двух функциях, это callswitch и callback, думаю, что Вы уже догадались как реализовать задуманное.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Переназначил на esp01 порты для bme280 на gpio1 и gpio3 (это которые Rx и Tx и все заработало.

Сейчас заказал модуль nrf24le1 (хочу записать от 12В батарейки) хочу сделать уличный датчик на bme280 (хотя можно и htu21d), а дома esp с метеостанцией

Изменено пользователем pasha413

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Большое спасибо за отличный проект!

Собрал себе станцию, все работает, кроме обновления через веб.

Пишет: неверный формат файла.

Пытаюсь загрузить скомпилированный бинарник ESP8266_WS_V2.0_iT4IT.CLUB.ino.nodemcu.bin.

Загрузка файлов на флеш работает, проверил.

Судя по всему срабатывает это условие в index.htm:

if(file.type !== "application/octet-stream") {
    showAlert("Неверный формат файла");
    return false;
}

Пробовал в Mac OS с Safari и Chrome. Попробовал на Win10 с Edge - результат одинаков.

В чем может быть дело?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Dmitry Moshalkov доброе время суток. Проблема явно связана с расхождением mime типов. Необходимо узнать, что получается у вас при компиляции.

Т.к Вы пользуетесь MacOS, а она имеет родство с UNIX системами, то Вам должна быть доступна консольная утилита File, по крайней мере я буду на это надеяться. Вызовите контекстное меню действий над объектом (правой кнопкой мыши или два пальца touchpad), после этого нажмите клавишу ⌥Option (Alt) и в меню Вам станет доступен пункт копирования полного пути к файлу.

Откройте консоль и введите

file -b --mime-type

через пробел дополните команду вставив из буфера (⌘Cmd + V) скопированный ранее путь и отправьте это все на выполнение. На выходе Вы должны получить mime тип указанного файла. Например, такой.

application/octet-stream

Я смогу проверить, что получается при компиляции под MacOS только сегодня вечером.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Kitsum Спасибо за ответ!

Проверил - возвращает корректный тип

damMacBook-770:~ dam$ file -b --mime-type /Users/dam/Documents/Arduino/Scetches/ESP8266_WS_V2.0_iT4IT.CLUB/ESP8266_WS_V2.0_iT4IT.CLUB.ino.nodemcu.bin
application/octet-stream

При этом создается впечатление, что в браузер при перетаскивании передается некорректный. Попробовал еще и Яндекс.Браузер, эффект такой же. 😞

Попробую вечером покопать, какой тип передается в браузер (с другой стороны у меня и из под Windows та-же история... ). 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
11 минут назад, Dmitry Moshalkov сказал:

При этом создается впечатление, что в браузер при перетаскивании передается некорректный.

Если у Вас сейчас имеется возможность проверить, что происходит в браузере, то предложу изменить

if(file.type !== "application/octet-stream") {
    showAlert("Неверный формат файла");
    return false;
}

приведя его к такому виду

if(file.type !== "application/octet-stream") {
    showAlert("Неверный формат файла: " + file.type);
    return false;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, Kitsum сказал:

Если у Вас сейчас имеется возможность проверить, что происходит в браузере, то предложу изменить

 

Нет, к сожалению, проверить смогу только вечером. Проверю и отпишусь...

  • Thanks 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Kitsum  

Уважаемый автор. Благодарю за развернутые ответы. Прошу подсказать про Вашу функцию "индикация состояния". Если я правильно понимаю, то она задействует пины 0 и 2? Какие еще пины задействованы "неявно"?


/* Индикация состояния контроллера */
class smartBlink {
  public:
    /* доступные порты */
    typedef enum {
      gpio0 = 0,
      gpio2 = 2, // NodeMCU
    } port_t;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Kitsum

Поправил index.htm и получил неожиданный результат: mime-type не application/octet-stream а application/macbinary !

Как в Mac OS поменять тип - сходу не нашел. Поправил в index.htm:

if(file.type !== "application/octet-stream" && file.type !== "application/macbinary") {
    showAlert("Неверный формат файла");
    return false;
}

И все заработало.

Спасибо за помощь!

Цитата

if(file.type !== "application/octet-stream") {
    showAlert("Неверный формат файла: " + file.type);
    return false;
}

 

Снимок экрана 2018-11-07 в 18.39.58.png

  • Thanks 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Devilisimo порт 2 задействован для индикации состояния микроконтроллера (режим AP, STA и ход выполнения различных задач). На этом порту по умолчанию сидит светодиод практически на всех модулях ESP, я просто воспользовался его наличием.

Что касаемо типа port_t

typedef enum {
  gpio0 = 0,
  gpio2 = 2, // NodeMCU
} port_t;

он описан для явного указания на то, какие порты можно задействовать, и чтобы исключить ошибку при указании номера порта в конструкторе smartBlink. Смысл был в том, чтобы дать возможность выбора из списка, взамен самостоятельного указания значения

07.11.2018 в 15:47, Devilisimo сказал:

Какие еще пины задействованы "неявно"?

Мне кажется это не совсем корректное определение, все порты заданы явно, плюс об этом я должен был упоминать в статье. Порт 2 используется для индикации состояния и описан в файле tools.h. Порты: 12, 13 и 14 для управления нагрузкой и описаны в файле gpio.h. Порты 4 и 5 для работы с i2c шиной и описаны в файлах с примерами, это файлы, название которых начинается с users_ и имеющие расширение .h. Если не считать системные порты, занятые под собственные нужды ESP, то все остальное свободно.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
30.01.2017 в 16:43, Kitsum сказал:

Перед тем как устанавливать метеостанцию на постоянное место жительства, подтянуть GPIO-0 (пин D3 на плате NodeMCU) к питанию 3.3V. Во время данной процедуры, питание на контроллере должно отсутствовать.

Не совсем понимаю для чего это делать нужно. Я использую GPIO-0 и 14 для кнопок, они подтянуты функцией INPUT_PULLUP. На GPIO-15 почему-то кнопка не заработала, хотя как реле он работает. GPIO-12 и 13 я использую для управления реле, изначальная функция отключена. На GPIO-2 (D4) подключен датчик DHT22 , иногда почему-то показания падают на нули. Все работает почти стабильно, правда пришлось увеличить время опроса датчиков до 10с., но это не так важно.

Функционал станции: датчики наружные BME280 и BH1750, показания буду отправлять на народный мониторинг; внутри датчик DHT22 и CCS811; по показаниям СО и TVOC при соблюдении внутренней температуры и влажности будет открываться окно для проветривания; с кнопок можно так же можно открыть/закрыть и через команду mqtt, например с телефона.

Соответственно вопрос, как влияет функция индикации  и что нужно подправить в изначальном коде, что бы не было мучительно больно? 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
09.11.2018 в 09:27, Devilisimo сказал:

Не совсем понимаю для чего это делать нужно.

Все дело в баге ядра ESP при котором контроллер может зависнуть и от этого не спасет даже сторожевой таймер. Если при старте микроконтроллера на данном порту будет висеть логическая единица, то все отработает замечательно, в противном случае не отработаю какие-то внутренние процессы микроконтроллера. После старта можно пользоваться портом, как угодно.

Как проверить баг

  1. Оставьте порт GPIO-0 висеть в воздухе
  2. Подайте питание на микроконтроллер
  3. Попробуйте обновить прошивку через web интерфейс, на последнем этапе этой процедуры происходит перезапуск контроллера

При это в Serial мониторе можно наблюдать, что контроллер ушел на перезагрузку и не "вернулся". Далее сработает сторожевой таймер и в консоли появится запись об этом, но это не поможет и контроллер останется в мертвом состоянии.

При этом, если оставить GPIO-0 висеть в воздухе, а после подачи питания на микроконтроллер сбросить его через Reset порт (кнопкой) и повторить процедуру загрузки программы через web интерфейс, то все прекрасно отработает. Вот такой феномен.

09.11.2018 в 09:27, Devilisimo сказал:

Функционал станции: датчики наружные BME280 и BH1750, показания буду отправлять на народный мониторинг; внутри датчик DHT22 и CCS811

Я бы рекомендовал отказаться от датчиков DHT серии в пользу второго датчика BME280, благо их можно держать два на линии, как и некоторые другие датчики температуры и влажности и т.д

09.11.2018 в 09:27, Devilisimo сказал:

Соответственно вопрос, как влияет функция индикации  и что нужно подправить в изначальном коде, что бы не было мучительно больно? 

Естественно, что на одном порту мигать светодиодом и общаться с датчиком просто так не получится, но без паники, ничего не решаемого нет.

Есть два варианта

  1. Вырезать в коде все упоминание о smartBlink, можно оставить само описание класса, но все вызовы методов этого класса в основном коде должны быть закомментированы.
  2. Более интересный вариант подразумевает доработку вашего кода, а точнее той его части где происходит опрос датчика на порту GPIO-2

Первый вариант

Найдите в файле tools.h строку окончания описания класса smartBlink и инициализации объекта этого класса с именем blink.

} blink;

и приведите её к такому виду

};

Теперь найдите в проекте все вызовы методов объекта blink по такому шаблону

blink.

И закомментируйте их. Таких строк не много, думаю меньше одного десятка и все должны быть в файле webserver.h

Второй вариант

Теперь давайте рассмотрим более интересный вариант с сохранением функционала и датчика, и светодиода. Основа идеи очень проста и заключается в том, чтобы отключать мигание на время общения с датчиком т.к работа со светодиодом организованна по прерыванию с использованием внутреннего таймера микроконтроллера. Это прерывание происходит независимо от того какой код сейчас выполняется в основной программе и останавливает эту самую программу, но смертельно даже не это, а то, что он вмешивается в телеграмму, посылаемую по общему порту. И тут вся магия заканчивается и начинаются проблемы.

Нам стоит присмотреться к методам самого класса smartBlink среди которых есть два очень полезных.

void smartBlink::setMode(mode_t mode);
void smartBlink::previous();

Первый устанавливает новый режим обработки прерываний и соответственно мигания светодиода, а второй возвращает все обратно, а точнее возвращает предыдущий режим. В файле webserver.h оба эти метода применяются и позволяют отображать отображать индикацию процесса загрузки файлов через web сервер микроконтроллера, будь то файлы прошивки или файлы самого web сервера.

Модифицируйте свой код таким образом, чтобы до начала работы с общим портом (сбора данных с датчика DHT) происходил выбор режима, при котором светодиод выключен, а после окончания работы с портом возвращался предыдущий режим индикации.

blink.setMode(smartBlink::mode_off);
/*
    Ваш код должен находиться в этой части
*/
blink.previous();

И, в принципе, все. Я не буду бить себя в грудь и говорить, что это точно поможет т.к я отказался от использования датчиков DHT в любых проектах, но я склоняюсь в сторону положительного результата т.к он логичен, хоть и зависит напрямую от внутренних процессов в самом датчике.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
10.11.2018 в 11:05, Kitsum сказал:

Я бы рекомендовал отказаться от датчиков DHT серии в пользу второго датчика BME280, благо их можно держать два на линии, как и некоторые другие датчики температуры и влажности и т.д

Естественно, что на одном порту мигать светодиодом и общаться с датчиком просто так не получится, но без паники, ничего не решаемого нет.

Добрый день спасибо за Ваши советы, но я хотел бы уточнить.

Цитата

Я использую GPIO-0 и 14 для кнопок, они подтянуты функцией INPUT_PULLUP.

Цитата

На GPIO-2 (D4) подключен датчик DHT22 , иногда почему-то показания падают на нули. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Devilisimo Порт GPIO-2 уже занят штатным светодиодом ESP (по крайней мере для ESP-12X) и объектом blink, описанным в файле tools.h, который и управляет этим светодиодом. Вы выбрали порт, который не висит "свободно в воздухе". Я указал на это в сообщении выше, а также на то, что нужно сделать. Но даже после исправления в коде на порту GPIO-2 останется висеть распаянный на фабрике светодиод, который еще и управляется низким логическим уровнем, что в свою очередь говорит о наличие на порту (со второго "конца" светодиода) напряжения 3.3V которые оказываются на ноге Data вашего датчика. Все эти моменты в комплексе и дают Вам тот результат, который имеется на данный момент. Я вообще удивлен, что датчик испытывает трудности только иногда, а не в течении всего времени, пока на плату подано напряжение. В любом случае, воспользуйтесь одним из двух советов о которых я Вам писал выше, и если не поможет, то выпаивайте штатный светодиод, но перед этой операцией обратитесь к актуальной схеме Вашего модуля, кстати в ней Вы найдете ответ почему кнопка на GPIO-15 не заработала, скорее всего этот порт подтянут к земле.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
22 часа назад, Kitsum сказал:

@Devilisimo Порт GPIO-2 уже занят штатным светодиодом ESP (по крайней мере для ESP-12X) и объектом blink, описанным в файле tools.h, который и управляет этим светодиодом.

Спасибо за совет. Пытаюсь вернуться к датчику BME280. Столкнулся с неопреодолимым сопротивлением. Показания на нулях. Датчик CCS811 и дисплей на шине работает исправно. Пробовал разные датчики, в т.ч. BH1750. Пробовал сброс и перепрошивку на старую, рабочую точно, версию. Не понимаю что происходит.

{"out_light":-2.00,"CCS811_ppm":692.00,"CCS811_ppb":44.00,"BME280_in_temperature":0.00,"BME280_in_humidity":0.00,"BME280_in_pressure":0.00,"rssi":-62.00}

Уже просто замкнутый круг. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день.

Очень долго мучался с данной проблемой, прям спать не мог. Почему-то решение пришло неожиданно, после проверки датчиков на nano. Добавил конфигурацию датчиков и все снова заработало, не знаю с чем бы это могло быть связано.  До этого почему-то работало в упрощенном режиме без проблем.

BME280I2C::Settings
settings_out(
  BME280::OSR_X1,
  BME280::OSR_X1,
  BME280::OSR_X1,
  BME280::Mode_Forced,
  BME280::StandbyTime_1000ms,
  BME280::Filter_Off,
  BME280::SpiEnable_False,
  BME280I2C::I2CAddr_0x76
),
settings_in(
  BME280::OSR_X1,
  BME280::OSR_X1,
  BME280::OSR_X1,
  BME280::Mode_Forced,
  BME280::StandbyTime_1000ms,
  BME280::Filter_Off,
  BME280::SpiEnable_False,
  BME280I2C::I2CAddr_0x77
);
BME280I2C BME_OUT(settings_out), BME_IN(settings_in);

 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Devilisimo доброе время суток. Рад, что у все получилось, но не затруднит ли Вас описать точное количество и типы датчиков на i2c шине в те моменты, когда вылетала ошибка? Не совсем ясно, сколько датчиков BME использовалось по факту до того момента, когда была добавлена конфигурация "для двух датчиков". На Nano проверяли путем подключения одного датчика и запуска одного из стандартных примеров?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
12 минут назад, Kitsum сказал:

@Devilisimo доброе время суток. Рад, что у все получилось, но не затруднит ли Вас описать точное количество и типы датчиков на i2c шине в те моменты, когда вылетала ошибка? Не совсем ясно, сколько датчиков BME использовалось по факту до того момента, когда была добавлена конфигурация "для двух датчиков". На Nano проверяли путем подключения одного датчика и запуска одного из стандартных примеров?

В проекте было активировано по сути два датчика - CCS811 и BME. Пробовал разное количество и комбинации. Конфигурация как таковая и до этого была, просто не были прописаны настройки .

Settings

Про Nano  Вы совершенно правы. 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Kitsum  Соответственно хотел спросить такой вопрос. На суточном графике нет отображения всех параметров. Что на это влияет?

Графики по каждому отдельно параметру отображаются без проблем.

image.thumb.png.558713941f1b17a1aa7989ce96038dd6.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
31 минуту назад, Devilisimo сказал:

На суточном графике нет отображения всех параметров. Что на это влияет?

Все очень просто, я не стал реализовывать автоматическое добавление параметров на общий график т.к сложно сделать что-то, что подойдет большинству. Вот с единичным параметром все просто, графики для них одного стандарта и одного цвета, тут работает правило единообразия, если конечно так можно выразиться. А вот в общем графике я предпочитаю видеть влажность в виде градиентной заливки синего цвета, а освещенность в виде кривой желтого или оранжевого цвета, так и со всеми остальными параметрами. Соответственно у Вас свои предпочтения, вы какое оформление предпочитаете?

Есть два варианта, как выйти из этой ситуации:

  1. В файле index.htm самостоятельно правите в нескольких местах код и приводите оформление к желаемому виду.
  2. Реализовать в панели управления раздел, позволяющий править оформление графика для всех сенсоров и там каждый кастомизируется как хочет.

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

Да и вторая версия задумывалась как исправление косяков первой, но в первую очередь я попытался реализовать хотелки форумчан, ну а получилось или нет, это судить им и Вам.

Если сообщество будет заинтересованно, то появится третья версия, но скорее всего на контроллере ESP32.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Kitsum Вопрос у меня совсем не к оформлению, меня все устраивает))  Вопрос  почему только данные освещенности отображаются на графике, мне нужны хотя бы стандартные - давление, влажность и температура. Может проблема в именование датчиков? Как их правильно назвать, что данные поттягивались?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Devilisimo Объект общего графика не строится автоматически, все правится руками в коде. Данные освещенности отображены т.к совпали с одним из свойств метода самого графика. Я указал на два варианта решения задачи - править все каждый раз руками или дополнить интерфейс панели управления. В данном случае первый вариант будет самым простым и быстрым, для этого ознакомьтесь с функцией обработки нажатия кнопки графика.

$("#graph").click(function() {
	/* ... */
});

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, спасибо. Сам понял свою ошибку. Не нужно переименовывать: out_pressure  -  in_temperature. И тогда будет счастье. Эти имена действительно завязаны с web-страницей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Похожие публикации

    • Автор: Kitsum
      Модуль предназначен для системы мониторинга Zabbix. Работает в качестве отдельного демона и осуществляет транзит сообщений от брокера до хостов в системе мониторинга. Подробное описание модуля можно посмотреть в следующей теме.
       
    • Автор: Kitsum
      Демон осуществляет транзит данных с MQTT брокера в СУБД MySQL. Можно переправлять как все сообщения, так и конкретные топики. Подробное описание можно посмотреть в следующей теме.
       
    • Автор: Kitsum
      Доброе время суток.
      Сегодня пойдет речь о том, как переправлять данные с MQTT брокера в базу данных MySQL. Транспортировать будем как сами адреса, так и значения всех топиков, на которые оформлена подписка. Данную задачу нельзя назвать распространенной, но все же, она имеет место быть и может пригодиться в том случае, если данные востребованы в системах не способных работать с MQTT протоколом самостоятельно или брокер находится в изолированной системе, а данные востребованы, например, в GUI за её приделами.

      Для осуществления задуманного нам потребуется самостоятельный процесс, который сыграет роль транспортного узла между MQTT брокером и базой данный MySQL. А значит, его придется где-то держать. В моем случае, это сервер под управлением операционной системой Linux Ubuntu 16.04.3 и дальнейшее описание будет под неё, но для других ОС действия аналогичные.
      Сам демон будет написан на Python и для его работы нам потребуется:
      python3 python-pip python-dev libmysqlclient-dev библиотека paho-mqtt для python https://pypi.python.org/pypi/paho-mqtt библиотека mysqlclient для python https://github.com/PyMySQL/mysqlclient-python Но начнем мы, в первую очередь, с подготовки базы данных.
      На плечи MySQL ляжет не только хранение, но и частичная обработка данных. Для этих целей нам потребуется отдельная база, хранимая процедура и функция с реализацией небольшой логики, и пользователь с ограниченными правами под чьим именем мы будем обращаться к ним. В конце поста, кроме самого демона, будет опубликован .sql файл, который достаточно просто импортировать, например с помощью стандартный средств базы данных
      mysql -uroot -p Вводим пароль администратора MySQL и импортируем наш .sql файл, но прежде, дочитайте статью до конца, возможно, Вы захотите внести свои изменения.
      mysql> source /media/mqttMySqlClient.sql После этого будет получен следующий результат:
      Создана база (схема) с именем mqtt Пользователь с именем mqtt-agent и паролем p@$$w0rd имеющий возможность подключаться с внешних адресов Пользователю будут назначены ограниченные права (только EXECUTE) в этой схеме Будет добавлена процедура update_topic, на которую ляжет задача добавления и обновления данных Будет добавлена функция get_topic для упрощения поиска данных На тот случай, если Вы захотите внести изменения или создать все ручками, рассмотрим содержимое sql файла.
      Если схема mqtt не существует, она будет создана
      CREATE DATABASE IF NOT EXISTS `mqtt`; Аналогичным образом будет создан пользователь mqtt-agent. Если необходимо конкретизировать, с какого адреса будет производиться подключение под этим пользователем, то замените % на доменное имя или ip адрес хоста. Если планируется использовать демона на том же сервере где установлен MySQL, замените % на localhost. Также разрешено не более 2 активных подключений, измените это значение на необходимое Вам.
      CREATE USER IF NOT EXISTS 'mqtt-agent'@'%' IDENTIFIED BY 'p@$$w0rd' WITH MAX_USER_CONNECTIONS 2; Пользователю будут выставлены ограниченные права. Ему будет разрешено пользоваться только хранимыми процедурами и функциями. Никакие самостоятельные запросы выполнять нельзя.
      GRANT EXECUTE ON `mqtt`.* TO 'mqtt-agent'@'%'; Переходим к работе с самой схемой
      USE `mqtt`; Будет создана таблица topics со следующей структурой.
      md5 - содержит уникальный одноименный хеш полученный из полного адреса топика. Именно по этому ключу и будет производиться поиск данных. Почему именно по нему, а не по самому имени? Дело в том, что md5 хеш имеет фиксированную, заранее известную, длину, что нельзя сказать о имени топика. Именно это ограничение не позволит сделать имя топика первичным ключом и явно идентифицировать данные в таблице. time - содержит UNIX время добавления/обновления данных по конкретному топику (по умолчанию GMT+0) topic - адрес топика. В контексте, упомянутого ранее, поля md5, не несет для нас никакой смысловой нагрузки. value - данные опубликованные в топике. DROP TABLE IF EXISTS `topics`; CREATE TABLE `topics` ( `md5` varchar(32) NOT NULL, `time` bigint(20) DEFAULT NULL, `topic` text, `value` text, PRIMARY KEY (`md5`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Теперь необходимо создать хранимые процедуры и функции, но сделать это будет невозможно из-за присутствие в их синтаксисе разделителя совпадающего с концом данных в sql запросе - ";" Чтобы избежать этот неловкий момент, изменяем разделить на произвольный.
      DELIMITER $$ Создает процедуру update_topic. Она принимает в качестве входных параметров два значения, адрес топика и опубликованные данные. Оба параметра являются текстовыми. Процедура, вычисляет md5 хеш из адреса топика и уже по нему производит поиск записи в таблице. Если запись не будет найдена, она будет создана, в противном случае данные в поле value будут обновлены. Данная процедура должна ускорить работу демона и избавить его от задержек, которые были бы неминуемы при выполнении этих же запросов на стороне клиента.
      DROP PROCEDURE IF EXISTS `update_topic`$$ CREATE DEFINER=CURRENT_USER() PROCEDURE `update_topic`(topic text, value text) BEGIN declare nMD5 varchar(32) default md5(topic); declare NUM bit; declare uTime bigint(20) default UNIX_TIMESTAMP(); SELECT COUNT(t.md5) INTO NUM FROM topics t WHERE t.md5 = nMD5; if NUM <> 1 then INSERT INTO topics VALUES(nMD5, uTime, topic, value); else UPDATE topics t SET t.time = uTime, t.value = value WHERE t.md5 = nMD5; end if; END$$ Также будет добавлена функция get_topic. Она необходима для запроса данных от имени созданного ранее пользователя и ограничений, наложенных на него. Функция принимает адрес топика в текстовом виде, производит вычисление md5 хеша и основываясь на его совпадении с имеющимися записями выводит значение поля value искомого топика.
      DROP FUNCTION IF EXISTS `get_topic`$$ CREATE DEFINER=CURRENT_USER() FUNCTION `get_topic` (topic text) RETURNS text BEGIN declare hMD5 varchar(32) default md5(topic); declare topicValue text; SELECT t.value INTO topicValue FROM topics t WHERE t.md5 = hMD5; RETURN topicValue; END$$ И в завершении всего, будет восстановлено стандартное значение разделителя.
      DELIMITER ; На этом разбор sql файла можно считать законченным. Он не содержит каких-либо сложным манипуляций и должен быть понятен. Все эти операции можно выполнить руками, но я совету воспользоваться импортом, как и было описано ранее.
      Переходим к демону
      В первую очередь устанавливаем необходимые пакеты.
      sudo apt-get install python3 python-pip python-dev libmysqlclient-dev Устанавливаем недостающие библиотеки для Python
      pip install paho-mqtt mysqlclient Добавим пользователя из-под которого будет запускаться демон
      sudo useradd --shell /usr/sbin/nologin --system mqtt-agent Выставляем все необходимые права (каталог /media как пример)
      sudo chown mqtt-agent:mqtt-agent /media/mqttMySqlClient.py sudo chmod 0700 /media/mqttMySqlClient.py Добавляем демона в автозагрузку через планировщик задач и от имени созданного пользователя
      sudo crontab -u mqtt-agent -e Добавляем в конец следующую запись
      @reboot /media/mqttMySqlClient.py start Запускаем демона от имени все того же пользователя
      sudo -u mqtt-agent /media/mqttMySqlClient.py start Это основное, что требуется сделать на сервере для организации работы демона.
      Переходим к разбору настроек программы
      Т.к изначально за основу была взята концепция другого демона из ветки Zabbix, то конфигурация перекочевала оттуда и аналогично разбита на несколько секций.
      """ Настройки MQTT """ mqtt_server = "mqtt.it4it.club" mqtt_port = 1883 mqtt_login = "" mqtt_password = "" mqtt_client_id = "mqttMySqlClient" Настройки подключения к брокеру. Все должно быть интуитивно понятным. Помните, что при совпадении идентификаторов клиентов, они начнут конкурировать за подключение и по очереди терять связь. Не допускайте их совпадений.
      """ Список топиков для подписки """ subscribe = { '$SYS/#', '#', } Список топиков для подписки указывается через запятую и в кавычках.
      """ Настройки MySQL """ mysql_host = "127.0.0.1" mysql_port = 3306 mysql_user = "mqtt-agent" mysql_passwd = "p@$$w0rd" mysql_schema = "mqtt" mysql_log_file = "/var/log/mqttMySqlClient.log" Настройки подключения с MySQL серверу также не должны вызывать вопросов.
      """ Настройки общие """ pid_file = "/tmp/mqttMySqlClient.pid" Последний параметр указывает на размещение .pid файла демона.
      Команды управления классические
      start - запуск в режиме демона stop - остановка в режиме демона restart - перезапуск в режиме демона window - запуск в оконном режиме, также позволяет запускать процесс в операционных системах Windows После запуска, демон пытается установить связь с MQTT брокером и пока это не произойдет, связь с MySQL сервером устанавливаться не будет. Если во время работы, связь с брокером будет потеряна то в принудительном порядке, будет разорвано соединение с базой данных. Таким образом, по активным сессиям MySQL сервера можно судить о наличии связи у демона с брокером. Во время простоя, а в нашем случае, это отсутствие потока данных от брокера, для проверки связи с сервером базы данных будет использована процедура эмуляции ping для MySQL сервера. Она представляет из себя простую арифметическую задачу на сложение не приводящей к работе с данными в базе. Операция выполняется крайне быстро и её удачное выполнение сигнализирует клиенту о наличии связи с базой, а базе об активности клиента. В связи с этим, периодическая активность клиента при отсутствие данных от брокера, является показателем нормальной работы.
      И на последок
      Если вы хотите произвести выборку из таблицы под именем пользователя используемым по умолчанию и с его ограничениями. Необходимо воспользоваться функцией get_topic с указанием полного адреса, интересующего топика.
      select mqtt.get_topic('$SYS/broker/version'); В ответ мы получим
      +---------------------------------------+ | mqtt.get_topic('$SYS/broker/version') | +---------------------------------------+ | mosquitto version 1.4.8 | +---------------------------------------+ 1 row in set (0,00 sec) На этом пока все.
      Файлы проекта: 
      PS: Это тестовая версия демона и возможно она будет претерпевать некоторые изменения.
       
    • Автор: Kitsum
      Хотите помочь проекту или спонсировать новый?
      Yandex.Money PayPal.me Тема проекта
       
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

×