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

Kitsum

Пользователи
  • Публикации

    424
  • Зарегистрирован

  • Посещение

  • Дней в лидерах

    234

Сообщения, опубликованные пользователем Kitsum


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

    08.05.2020 в 09:18, post125 сказал:

    Добрый день! Можно ли добавить закладки в web-интерфейсе помимо "in" и "out".  У меня 39 датчиков на одной странице, трудно ориентироваться, хотелось бы распределить на 3-4 страницы. На форуме решения не нашел. Заранее благодарен за ответ

    Думаю, да, тут больше работы в самом web интерфейсе нежели на стороне микроконтроллера. Давайте начнем с последнего.

    В прошивке микроконтроллера идем в файл sensors.h b и ищем объект отписывающий типы листы на которых отображаются элементы.

    class device {
      public:
        typedef enum list_t {out = 1, in = 2};
      
      /* ... */
    }

    Можете расширить тип list_t и указать свои варианты

    typedef enum list_t {out = 1, in = 2, garage = 3, bathroom = 4};

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

    sensors.add(new knob_t(-100, 0, "1", "RSSI", "dbm"), device::garage, "rssi",[&](){ 
    	return wifi.isConnected() ? WiFi.RSSI() : 0; 
    });

    На этом работа с прошивкой закончена и переходим к web интерфейсу.

    В файле index.htm имеется блок, отвечающий за размещение датчиков.

    <div class="sensorsContent" hidden>
            <div class="menu">
                <div id="sensors" class="list1"></div>
                <div id="graph"></div>
                <div id="settings"></div>
            </div>
            <div id="list1"></div>
            <div id="list2" hidden></div>
            <div prototype hidden>
                <div class="sensor">
                    <div class="title">{title}</div>
                    <div class="unit">{unit}</div>
                    <input class="knob {name}" data-width="200" data-displayPrevious=true data-fgColor="#FFF" data-skin="tron" data-thickness=".1" value="0" data-min="{min}" data-max="{max}" data-step="{step}" readonly>
                </div>
            </div>
        </div>

    Все датчики, в зависимости от их целочисленного идентификатора в нашей прошивке микроконтроллера в типе list_t помещаются в <div> блоки

    <div id="list1"></div>
    <div id="list2" hidden></div>

    Добавляем новые листы

    <div id="list1"></div>
    <div id="list2" hidden></div>
    <div id="list3" hidden></div>
    <div id="list4" hidden></div>

    Вообще правильнее было автоматизировать процесс создание листов, как это сделано с датчиками, но это отдельная история

    Теперь необходимо распространить на новые листы необходимые стили, для этого в разделе с css разметкой ищем

    .sensorsContent #list1,
    .sensorsContent #list2 { max-width: 90%; margin: auto; min-height: calc(100vh - 160px); }

    Аналогичным образом добавляем новые листы

    .sensorsContent #list1,
    .sensorsContent #list2,
    .sensorsContent #list3, 
    .sensorsContent #list4 { max-width: 90%; margin: auto; min-height: calc(100vh - 160px); }

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

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

    Но предварительно, мы сделаем еще одно добавление, а точнее его уже сделаете Вы. Каждая иконка хранится в виде BASE64 хэша бинарной иконки в формате PNG. Если мне не подводит память, то размер иконки составляет 35х35 пикселей. Если Вы не меняете глобально этот интерфейс, то советую не использовать иконки другого размера для данного меню.

    Для перевода PNG иконок в используемый формат я использовал этот ресурс https://www.base64-image.de/

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

    .menu #sensors.list

    Вы найдете следующее, я укажу в виде фото т.к объем текста просто огромный. Надеюсь Вы используете какой-то более мене нормальный редактор, и он преобразует этот огромный набор текста в читаемый вид, я использую Visual Studio Code

    image.png

    По аналогии добавьте свои иконки для новых элементов меню, не забудьте менять номера листов

    На этом этапе Вы уже должны иметь набор новых иконок с именами: list1, list2, list3 и т.д. Теперь их необходимо организовать в меню. И тут мы возвращаемся к нашему начальному html блоку, который был описан в самом начале, это тот, в котором мы добавляли новые листы.

    image.png

    Давайте теперь добавим и таким образом отобразим все имеющиеся иконки.

    image.png

    На этом этапе в интерфейсе имеются все новые иконки, но логика работы их переключения все еще не изменена. Давайте исправим это. Для этого нам понадобится внести изменения и JavaScript код нашего с Вами проекта. Это последний и самый сложный этап.

    Ищем следующий код

    $(".menu #sensors").click(function() {
        var list = $(this).attr("class");
        switch (list) {
            case 'list1': $("#list1").fadeToggle('slow', function(){ $("#list2").fadeToggle('slow'); }); break;
            case 'list2': $("#list2").fadeToggle('slow', function(){ $("#list1").fadeToggle('slow'); }); break;
        }
        $(this).toggleClass("list1", !$(this).hasClass("list1")).toggleClass("list2", !$(this).hasClass("list2"));
    });

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

    Давайте преобразуем его в следующий вид. Сразу скажу, что так делать не правильно, как и многое в этом проекте, но так будет нагляднее и Вам не придется делать лишние шаги которые могут запутать. В идеале, можно добавить новый, одинаковый идентификатор, для все наших слове (<div>) и по нему плавно скрыть все элементы и потом плавно показать нужный.

    $(".menu #sensors").click(function() {
        var list = $(this).attr("class");
    
        $("#list1").hide();
        $("#list2").hide();
        $("#list3").hide();
        $("#list4").hide();
    
        $("#"+list).show();
    });

    Теперь ищем код который скрывает первоначальные элементы меню

    if (hideSensorsMenu) $(".menu #sensors.list1").css("display", "none");

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

    PS: я не могу ручаться за достоверность всех описанных действий т.к не проверял их на практике. Это просто совет, который должен направить Вас, ... и только направить.

    • Thanks 1

  2. 28.04.2020 в 12:15, Tarisper сказал:

    Хочу внести свои изменения и сохранить всё у себя га git в открытом доступе. Есть  ваш проект на гите?

    На данный момент нет. На мой взгляд, он требует большой переработки.

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


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

    18.03.2020 в 10:56, IvAn сказал:

    Насколько я понял, проблема с диапазоном 1...-1 в графиках скорее всего из-за этого:

    String sensors::clear(float value) {
      if ((int)value == 0) return "0";
      else if (value - (int)value == 0) return String((int)value);
      else return String(value);
    }

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

    String sensors::clear(float value) {
      if ((int)value == value) return String((int)value);
      return String(value);
    }

     

    14.03.2020 в 11:43, Neon сказал:

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

    Вроде уже было упоминание об NRF в теме и люди делились рабочими вариантами.

    28.03.2020 в 17:18, 451-F сказал:

    1. Почему при наличии свободного места на флеш, статистика датчиков:

    - хранится всего 1 день.

    - слетает после потери питания .

    Хотелось бы реализовать запись в энергонезависимую память данных на длительный срок.

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

    Конечно, если очень хочется, то это можно реализовать. В первую очередь надо определиться с приемлемым сроком жизни устройства и уже отталкиваться от этого. На сколько я помню, память рассчитана на 100000 циклов перезаписи. Значит если записывать данные каждый час, то примерно через 11 лет устройство выйдет из строя. Естественно это все очень грубо посчитано, но закроем на это глаза.

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

    На данный момент, при передачи данных для графика в web интерфейс, дополнительно передается время в миллисекундах с последней добавленной точки, а уже на стороне клиента (в браузере) берется время устройства (компьютер, телефон, планшет) и зная время последней точки, мы можем разрисовать временную шкалу графика. Это очень простая система, не требующая никаких часов на микроконтроллере. В принципе, наверное, только из-за простоты я и выбрал её. Но и другие варианты тоже имеют право на жизнь.

    28.03.2020 в 17:18, 451-F сказал:

    2. Наблюдается проблема такого плана. 

    Esp корректно отрабатывает подключение к wifi сети при обрыве питания, но в случае перезагрузки роутера, плата отказывается повторно подключаться к сети. 

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

    image.png

     


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

    13.02.2020 в 14:44, Vladik сказал:

    Попробовал подключить через 4G WiFi роутер станцию к 4g интернету Tele2, станция НЕ работает. И с Билайном не работает.

    WiFi имеет много настроек и стандартов, начиная от стандартов заканчивая каналом (частотой). Я бы посоветовал проверить настройки маршрутизатора с которым получилось установить связь и продублировать их на маршрутизаторе с которым возникли проблемы.

    14.02.2020 в 11:04, IvAn сказал:

    На графиках перестали показываться отрицательные значения после последнего обновления. Где поискать?

    Это весьма странно. Я взял тестовый программный сенсор и проверил на нем, воссоздать не получилось. Давайте разбираться.

    Добавьте следующий датчик в Ваш код.

    sensors.add(new knob_t(-100, 100, "1", "Test", "???"), "test",
      [&](){ return random(-100, 10); }
    , true);

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

    image.png image.png

    • Like 1

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

    @see по поводу измерения скорости ветра. Да, в Arduino IDE есть баг, точно не проверял, но вроде на версиях выше 2.5.2 прерывания могут вызывать падения программы (любой). Проверил на чистом проекте, в котором были только прерывания и вывод в Serial. Не буду ходить вокруг да около, по итогу внес небольшие правки в код. Для эксперимента используйте архив с средой разработки опубликованный на Yandex диске, ссылка в загрузках. Используйте код опубликованный в исходниках, в файле users_wspeed.h

    Первым делом определитесь с используемым портом, допустим это GPIO14 (D5). Укажите этот порт в users_wspeed.h

    #define  windSpeed_Pin 14 // GPIO микроконтроллера к которому подключен чашечный анемометр

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

    //#include "users_auto.h";      // Пользовательская конфигурация датчиков, именно тут описывается с какими датчиками работать
    //#include "users_bme280_x2.h"; // Пример для двух датчиков BME280
    //#include "users_ds18.h";      // Пример для датчиков DS18B20
    #include "users_wspeed.h";      // пример для самодельного анемометра

    В основном файле закомментируйте функцию в которой также задействован порт GPIO14

    // gpio_14(); // Расхождение расчетной абсолютной влажности между показаниями с двух датчиков, например, BME280

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

    Я проверил код для датчика скорости ветра на живом контроллере, все работает.

    image.png

    24.01.2020 в 10:49, Олег сказал:

    Помогите разобраться пожалуйста!

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

    25.01.2020 в 15:02, MaxOn сказал:

    Исправил по Вашей рекомендации, согласно второму пункту, все работает как надо! Моя благодарность!

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


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

    18.01.2020 в 19:02, MaxOn сказал:

    Что я делаю не так?

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

    Или можно исправить оплошность и в файле wifi.h найти строку

    if (!MDNS.begin(hostname.c_str())) { console.println("Error setting up MDNS responder!"); }

    и заменить её на

    if (!MDNS.begin(hostname.c_str())) { 
      #ifdef console
        console.println("Error setting up MDNS responder!"); 
      #endif
    }

    Я загружу исправления в ближайшее время.

    • Thanks 1

  7. 04.01.2020 в 16:55, Sergey Mlynarchyk сказал:

    А кто-нибудь пробовал подключаться к интернету через что-то типо GSM-модуля SIM800L или подобного?? И получиться ли это реализовать?

    Я бы не тратил на это время. Намного надежнее и практичнее взять LTE+WIFI маршрутизатор, например, БУ по объявлениям. Это избавить от кучи подводных камней. А если Вы сами довольно много времени будите проводить в зоне действия будущей точке доступа, то лучше взять хороший маршрутизатор и возможность подключения LTE модема или со встроенным модемом. Это окупит себя многократно и сэкономит кучу бессонных ночей.


  8. @post125 да, подключение через контроллер посредник будет самым выгодным. На сколько мне помнится, Вы уже скидывали в эту тему свои наработки. Вот бегло нашел первый пост https://it4it.club/topic/55-meteostanciya-na-esp8266-ot-it4itclub/?do=findComment&comment=1203, начиная с него можно почитать о Вашем опыте. Но хоть это больше про I2C, думаю заинтересованным будет интересно.

     

    • Like 1

  9. 25.11.2019 в 16:15, Ruslan сказал:

    Как сделать что бы А0 не реагировала на1 при снятой сигнализации.

    Просто закомментируйте не нужный вам вызов управления A0

    24.12.2019 в 23:10, Евгений сказал:

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

    Прикрепите пожалуйста весь текст ошибки т.к по скриншоту невозможно определить где проблема.


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

    15.12.2019 в 19:41, post125 сказал:

    А ESP32 на горизонте не виднеется?

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

    image.png

     

    @kamikozz Рад, что Вы с таким азартом отнеслись к этому проекту. Но, к сожалению, Вы упустили главную мысль - проект модульный и wifi.h один из модулей с малым количеством зависимостей, а если быть точным, то от него не зависят другие модули вообще. Вы вправе вообще удалить его или полностью переписать согласно необходимой логике работы.

    Главная идея wifi.h, это балансировка между режимами AP и STA. Нормальным считается, что контроллер подключен к домашней беспроводной сети, если этот пункт не выполнен, то контроллер переходит в режим AP и периодически пытается найти домашнюю сеть. В этом режиме мы получаем возможность его перенастроить т.к контроллер мог потерять домашнюю сеть из-за того, что у неё изменился SSID или контроллер переехал на другое место жительства.

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

    Но у меня вопрос, зачем Вам режим AP+STA? Возможно лучше и надежнее подключить второй контроллер к общей с первым точке доступа и просто перекидываться через HTTP API запросами?

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

    25.12.2019 в 15:40, kamikozz сказал:

    слегка подправить front-end, разбив разметку, стили, скрипты в отдельные файлы (возможно, дольше первоначальная загрузка, зато, имхо, это лучше чем динамическая подгрузка скриптов)

    Кстати, именно по этой причине много кода WEB интерфейса размазано по малому количеству файлов, в Index.htm валяется и css и java, а в css сохранены некоторые картинки. Динамическая подгрузка компонентов. Все это позволяет уложиться в минимальное, как я это видел, количество tcp соединений с контроллером т.к браузер загружает все компоненты страницы параллельно, а текущий web сервер не способен обрабатывать более одного соединения за раз, да и у контроллера попросту нет на это ресурсов. Обязательно помните об этом.

    Но вернемся к wifi.h. Если Вам ближе режим AP+STA место центрального маршрутизатора для обоих контроллеров, то просто удалите wifi.h и в основном файле добавьте необходимый режим. Убедитесь, что имеете доступ со стороны AP и STA. После этого можете начинать прикручивать сохраненные в config значения параметров для поднятия точки с нужным именем и для подключения к домашней точке доступа.

    @Neon @den48rus давайте разбираться с NRF. Под рукой, в текущий момент, её нет, но мы попробуем и пробежимся по основным моментам.

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

    vid_nrf24l01.jpg

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

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

    А теперь самое интересное. Например, в библиотеки RF24.h, которую, как мне кажется, используют многие, возможно использовать свой тип данных для передачи. Таким образом Вы можете объявить свою структуру, в которой можно определить что угодно. Допустим не просто пустые и безликие данные, а тип сенсора, показания с нескольких датчиков и, например, напряжение питания удаленного устройства.

    struct { 
      byte type; 
      float temperature; 
      float humidity; 
      float voltage;
    } nrf_data;
    
    nrf_data remote_sensor;

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

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

    sensors.add(new knob_t(0, 100, ".01", "Влажность", "%"), "Humidity",
        [&](){ return remote_sensor.humidity; }
    );

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

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

     

    • Like 2
    • Thanks 2

  11. Файлы проекта обновлены. Добавлена поддержка последних, на момент публикации, версий Arduino IDE и модуля ESP8266. Добавлены небольшие исправления и доработки. При использовании, указанных в основном посте, версий программных компонентов Вы не получите вылет программы с критической ошибкой. Исправлена серьезная ошибка в медианном фильтре, кто использует проект обязательно обновите у себя объект medianFilter_t, он находится в tools.h

    В разделе загрузок, добавлена утилита для загрузки файлов web сервера во flash память. Также в описании к файлам, добавлена ссылка на скачивание готовой Arduino IDE со всеми библиотеками, утилитами, и последней версией проекта.

    Для работы модуля загрузки файлов во Flash может понадобится последняя версия Python https://www.python.org/downloads/

    • Like 1
    • Thanks 2

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

    06.12.2019 в 11:04, Андрей Иванов сказал:

    сканер по шине I2C не находит устройств.

    Значит ошибка в подключении имеет место быть. Для Вашей платы шина I2C была проинициализирована на портах D1 (SCL) и D2 (SDA). Возможно Вы их перепутали, или нет контакта или проблема на стороне датчиков. В любом случае, работа I2C сканера обкатана всеми участниками в этой теме и в его работоспособности нет сомнений. Кстати, он как раз и внедрялся для выявления подобных проблем. Еще раз все внимательно проверьте.

    Вот как выглядит его работа сейчас у меня

    image.png

    06.12.2019 в 11:04, Андрей Иванов сказал:

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

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


  13. @Андрей Иванов нет, нет. Вы указали вариант платы, на которой распаян модуль ESP8266. Вам следует проверить версию пакета ESP8266 установленного в Arduino IDE. Скорее всего Вы используете одну из последних, а необходимо установить ту, что указана в инструкции в первом посте. В ближайшее время я опубликую обновление с некоторыми исправлениями, и поддержкой последней среды разработки и пакета ESP8266.

    Также внимательно смотрите на версию используемой библиотеки ArduinoJson. Все это описано в инструкции.


  14. @emaus нет, так не получится т.к ключи Вашего массива никак не связаны с его значениями. Сейчас, условно, в $data[5] лежат одни данные, а через секунду совершенно другие и это можно устроить даже не добавляя новые записи в таблицу.

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

    while($row = $result->fetch_assoc()) {
    	$data[$row['topic']] = $row['value'];
    }

    Далее Вы можете легко обращаться к значениям по имени топика и делать это хоть с массивом, хоть с объектом json. А если потребуется перебрать все, что там есть, то можно использовать foreach, благо он есть во всех современных языках.


  15. @emaus не совсем понимаю, что Вы делаете т.к объяснение идет в контексте другой программы. Вам стоит предоставить Ваш код и более подробно описать что вы хотите сделать. И если этот вопрос никак не связан с текущим проектом, то лучше создать отдельную тему или напишите мне в приват.


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

    13.11.2019 в 14:50, Neon сказал:

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

    Нет не сложно, это все правится через HTML и CSS. В код контроллера ничего вносить не потребуется. Но Вы точно столкнетесь с проблемой быстрой выгрузки фоновой картинки если она будет храниться на SPI Flash. Если она будет не большого размера, то все будет хорошо и не придется придумывать костыли, как я это делал с облаками.

    14.11.2019 в 20:13, Neon сказал:

    установил 8 мб, скетчи работают, а вот метеостанцию запустить не удалось, похоже какая то проблема с SPIFFS

    так как светодиод моргает, в монитор инфу пишет, точку доступа создает, к ней подключаюсь и все, в браузере ничего

    Скорее всего Вы не залили файлы web сервера в вашу новую flash память. Этот этап описан в инструкции.

    • Like 1

  17. @emaus Доброе время суток. Давайте разбираться.

    В первую очередь нам нужно создать сертификаты. Я приведу пример с самоподписанным сертификатом, но в сети множество мануалов на эту тему, вплоть до получения сертификата у Let's Encrypt.

    СЕРВЕР

    Создание закрытого ключа для центра сертификации. Ключ будет защищен паролем.

    openssl genrsa -des3 -out ca.key 2048

    Создание сертификата для центра сертификации

    openssl req -new -x509 -days 99999 -key ca.key -out ca.crt

    Создание закрытого ключа для брокера mosquitto

    openssl genrsa -out srv.key 2048

    Создание запроса к центру сертификации по которому будет создан ключ сервера. Мы не задаем пароль для него т.к иначе придется его вводить каждый раз когда стартует mosquitto. И еще один важный момент, это заполнение поля "Common Name" в котором должно быть указано доменное имя сервера. Это необходимо для прохождения проверки подлинности на стороне клиента. Но если это невозможно, и Вы используете сервер в локальной сети, то эту проверку можно будет отключить на стороне клиента. Этот важный момент будет описан ниже.

    openssl req -new -out srv.csr -key srv.key

    Теперь осталось подписать сертификат сервера в нашем сервере сертификации. Потребуется ввести пароль которым защищен ключ сервера сертификации.

    openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out srv.crt -days 99999

    Теперь необходимо установить MQTT брокер. Я использую операционную систему Linux Ubuntu 18.04 и буду описывать установку для неё. Все команды выполняются от пользователя root.

    apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
    apt update
    apt install mosquitto

    Теперь созданы все необходимые файлы и каталоги и нам необходимо скопировать: сертификат центра сертификации (ca.crt), сертификат сервера (srv.crt) и ключ сервера (srv.key) в каталог который доступен mosquitto, например, /etc/mosquitto/certs

    По умолчанию конфигурационный файл сервера практически не содержит никаких настроек. Вот как он выглядит у меня.

    root@server:/# cat /etc/mosquitto/mosquitto.conf
    # Place your local configuration in /etc/mosquitto/conf.d/
    #
    # A full description of the configuration file is at
    # /usr/share/doc/mosquitto/examples/mosquitto.conf.example
    
    pid_file /var/run/mosquitto.pid
    
    persistence true
    persistence_location /var/lib/mosquitto/
    
    log_dest file /var/log/mosquitto/mosquitto.log
    
    include_dir /etc/mosquitto/conf.d

    Как мы видим, сервер читает все пользовательские конфигурационные файлы из каталога /etc/mosquitto/conf.d тут мы и разместим свой файл. Создайте любой файл в этом каталоге, например, tls.conf

    touch /etc/mosquitto/conf.d/tls.conf

    Записываем в него следующие параметры. По необходимости добавьте свои параметры конфигурации.

    port 8883
    cafile /etc/mosquitto/certs/ca.crt
    certfile /etc/mosquitto/certs/srv.crt
    keyfile /etc/mosquitto/certs/srv.key
    tls_version tlsv1.2

    Я использовал версию TLS 1.2 т.к на момент тестирования модуль SSL для Python не знал о версии 1.3. Вероятнее всего эту ситуацию можно поправить, но я не стал тратить на это время т.к цель ставилась просто запустить скрипт с использованием шифрования соединения с сервером.

    Перезапустим сервер так

    systemctl restart mosquitto

    или по старинке

    /etc/init.d/mosquitto restart

    Проверяем, что сервер запустился и прослушивает порт 8883

    netstat -plnt | grep mosquitto
    tcp        0      0 0.0.0.0:8883            0.0.0.0:*               LISTEN      24233/mosquitto
    tcp6       0      0 :::8883                 :::*                    LISTEN      24233/mosquitto

    Если что-то не так, то смотрим логи и анализируем ситуацию.

    СКРИПТ

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

    import ssl

    Вносим изменения в переменные описывающие где искать MQTT сервер и меняем порт.

    mqtt_port = 8883

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

    def start():
        global mqttReconnect
        global mysql
        try:
            mysql = mysqlDB(mysql_host, mysql_user, mysql_passwd, mysql_schema, mysql_port)
            mqttc = mqtt.Client(mqtt_client_id, True)
            # mqttc.on_log = on_log
            mqttc.on_connect = on_connect
            mqttc.on_disconnect = on_disconnect
            mqttc.on_message = on_message
            # !!!DANGEROUS!!! Be sure to remove "cert_reqs=ssl.CERT_NONE" if you use valid domain names in the COMMON NAME field of your certificate!
            mqttc.tls_set("/etc/mosquitto/certs/ca.crt", cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2);
            if len(mqtt_login) > 0:
                mqttc.username_pw_set(mqtt_login, mqtt_password)
            mqttReconnect = True
            while mqttReconnect:
                try:
                    alert('connecting to MQTT broker...')
                    mqttc.connect(mqtt_server, mqtt_port, 60)
                    mqttReconnect = False
                except Exception as e:
                    alert('could not connect to MQTT broker, reconnect after 10 seconds: ' + str(e), True)
                    time.sleep(10)
                while not mqttReconnect:
                    mysql.loop()
                    mqttc.loop(timeout=1.0)
        except Exception as e:
            alert('\nunexpected termination of the program: ' + str(e), True)

    Обратите внимание на следующую строку

    mqttc.tls_set("/etc/mosquitto/certs/ca.crt", cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2);

    Тут мы указываем где найти сертификат центра сертификации, по нему будет проверяться подлинность сертификата сервера. Также мы указываем версию TLS и, что !!!ОЧЕНЬ ВАЖНО!!! - мы говорим клиенту не проверять подлинность сертификата (cert_reqs=ssl.CERT_NONE). Это нужно только на время отладки или в том случае если поле "COMMON NAME", сертификата сервера, не соответствует фактическому адресу сервера или там указан только ip адрес.

    Я оставил об этом соответствующий комментарий строкой выше.

    # !!!DANGEROUS!!! Be sure to remove "cert_reqs=ssl.CERT_NONE" if you use valid domain names in the COMMON NAME field of your certificate!

    Осталось самое главное - проверить работоспособность.

    Запустите демона с параметром window чтобы увидеть дополнительную информацию и ошибки в ходе отладки

    <script dir>/mqttMySqlClient.py window

    Все должно заработать, проверил на своем домашнем сервере.


  18. @emaus доброе время суток.

    09.11.2019 в 13:31, emaus сказал:

    Скрипт я так понял не поддерживает mqtt работающий с SSL сертификатами ?

    В данном примере нет, но функционал шифрования добавляется с помощью метода tls_set с соответствующими параметрами. Посмотреть их можно тут https://www.eclipse.org/paho/clients/python/docs/

    09.11.2019 в 13:31, emaus сказал:

    И планируете ли Вы добавить в скрипт что бы он работал  в обратном порядке  ?

    К сожалению, это проблематично т.к единственный способ оперативно отслеживать изменения в СУБД это триггеры и по умолчанию они не позволяют вызывать внешние программы в самой ОС а только лишь исполняют код в пределах самой СУБД т.к это противоречит политике безопасности. Но сделать это возможно.

    Но гораздо более простой вариант, это отправлять сообщение в нужную ветку на брокер в той программе которая должна была вносить изменения в БД. Это не противоречит политике безопасности и гораздо проще чем компилировать собственные модули для СУБД.

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


  19. @Neon доброе время суток.

    11.11.2019 в 06:55, Neon сказал:

    А у esp32 есть какие то функции отсутствующие в esp8266?

    Да, это более современный контроллер и гораздо более производительный.

    11.11.2019 в 06:55, Neon сказал:

    У меня почему-то исчез вывод показаний RSSI, это произошло после нескольких перепрошивок esp

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

    Вот его код

    sensors.add(new knob_t(-100, 0, "1", "RSSI", "dbm"), device::in, "rssi",[&](){ 
      return wifi.isConnected() ? WiFi.RSSI() : 0; 
    });
    11.11.2019 в 06:55, Neon сказал:

    Кстати, запустил метеостанцию на esp01 :)

    Поставил на нее 4 МБ и датчик BME280

    Хороший опыт, рад, что у Вас все получилось)

    11.11.2019 в 06:57, Neon сказал:

    Обратил внимание , что в Ардуино IDE при в плате esp можно выбрать 8 и 16 мегабайт

    Выбираемые параметры разметки flash памяти в Arduino IDE зависят для конкретных плат, описанных в файле boards.txt для ESP8266 и отмеченных параметром flash_ld. Сами ld файлы располагаются в каталоге по относительному пути \hardware\esp8266\2.5.2\tools\sdk\ld и зависят от версии пакета ESP8266 (в примере 2.5.2) и от того используете Вы или нет Portable версию Arduino IDE. Для данного проекта я рекомендовал использовать контроллер с 4Mb Flash и разбивать её по схеме описанной в файле eagle.flash.4m3m.ld. А тут можно посмотреть их содержимое не копаясь в самой среде на своем компьютере https://github.com/esp8266/Arduino/tree/master/tools/sdk/ld В общем это очень интересная тема, но требует внимательности и не прощает ошибок.


  20. @Neon доброе время суток.

    Да действительно, Вы правы, файлы были обновлены, но этой ошибки там нет. Все дело в обновлении среды разработки и пакета ESP8266. Теперь можно использовать Arduino IDE v1.8.10 с поддержкой ESP8266 v2.5.2. И как раз в последних версиях пакета ESP8266 были переименованы некоторые функции и responseCodeToString теперь имеет имя без нижнего подчеркивания. Я постарался чтобы проект поддерживал одну из последних версий пакета.

    Также я выложил некоторые дополнительные наработки которые накопились у меня во время работы над ответами некоторым пользователям в этой теме. Теперь можно подсмотреть как добавит датчики DS18B20 или самодельный анемометр с импульсным выходом.

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

    • Thanks 1

  21. @Вадим Спасибо за ссылку. Метеостанция интересна, но меня больше заинтересовал плагин реализующий датчики. Как оказалось, он довольно стар и уже претерпел не мало изменений. Вот интересные ссылки по этой теме:

    Вероятнее всего я постараюсь использовать данный плагин на ESP32.

     

×
×
  • Создать...