• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

IoT Manager - сообщаем о багах

roiksv

Member
Жаль, уже хотел разнести данные для срабатывания датчиков "IoTmanager/+/+/setup" и просить в IoTmanager реализовать в настройках уровень отображения (2,3 и т.п.). Значит не судьба)). Получается как бы можно сделать "IoTmanager/+/+/setup" для данных в один конец. Придется мириться
 

roiksv

Member
Сейчас топики жестко привязаны (prefix + "/" + deviceID + "/" + device). Т.е /IoTmanager/+/+/control(status). Если не привязывать жестко можно было бы прятать информацию с экрана, которую нет надобности видеть каждый раз). Например в /IoTmanager/+/+/control(status) это переключатели или датчики, а /IoTmanager/+/+/+/control(status) это другая информация, например мин-макс порог срабатывания датчиков, который выставляется не каждый день. Соответственно и в IoTmanager тогда нужна настройка отображения этих уровней(/+/+/...). Т.е 2-подписка на +/+, 3-+/+/+
 

Mоnk

Member
Кто как выкручивается, убирая и восстанавливая кнопки и показания на экране...
CSS:
void initVar()
{
  id        [0] = "50"; // === 0 === Температура
  page      [0] = room;
  pageId    [0] = "52";
  sTopic    [0] = prefdev + "/DHT22_t";
  stat      [0] = setStatus(DHT22_tS + " °C");
  descr     [0] = "Температура";
  widget    [0] = "anydata";
  class1    [0] = "item rounded no-padding";
  style1    [0] = "";
  class2    [0] = "rounded padding";
  style2    [0] = "font-size:20px;float:left;height:50px";
  class3    [0] = "rounded padding";
  style3    [0] = "font-size:30px;text-align:right;height:50px"; 

  id        [1] = "51"; // === 1 === Влажность
  page      [1] = room;
  pageId    [1] = "52";
  sTopic    [1] = prefdev + "/DHT22_h";
  stat      [1] = setStatus(DHT22_hS + " %");
  descr     [1] = "Влажность";
  widget    [1] = "anydata";
  class1    [1] = "item rounded no-padding";
  style1    [1] = "";
  class2    [1] = "rounded padding";
  style2    [1] = "font-size:20px;float:left;height:50px";
  class3    [1] = "rounded padding";
  style3    [1] = "font-size:30px;text-align:right;height:50px";

  id        [2] = "52"; // === 2 === Нагреватель
  page      [2] = room;
  pageId    [2] = "52";
  sTopic    [2] = prefdev + "/lightblue";
  stat      [2] = setStatus(OFF);
  descr     [2] = "Нагреватель";
  widget    [2] = "toggle";
  more      [2] = ",\"iconClass\":\"ion-ios-flame-outline\",\"iconClassOff\":\"ion-ios-flame-outline\",\"iconStyle\":\"font-size:30px;color:#ff3d3d;\",\"iconStyleOff\":\"font-size:30px;color:#eee;\",\"descrStyle\":\"font-size:20px;line-height:1.5em;\"";
  defaultVal[2] = OFF;

  id        [3] = "53"; // === 3 === Button_Minus
  page      [3] = room;
  pageId    [3] = "52";
  sTopic    [3] = prefdev + "/B_Minus";
  widget    [3] = "simple-btn";
  class1    [3] = "item no-border col-xs-4"; // Размер колонки
  class2    [3] = "balanced";
  class3    [3] = "button button-calm button-fab button-outline icon ion-minus";
  style3    [3] = "height:80px;width:80px;";
  more      [3] = ",\"delay\":\"1000\"";

  id        [4] = "54"; // === 4 === Нагревать до
  page      [4] = room;
  pageId    [4] = "52";
  sTopic    [4] = prefdev + "/setpoint";
  stat      [4] = setStatus(String(setpoint) + "°");
  widget    [4] = "anydata";
  class1    [4] = "item no-border col-xs-4"; // Размер колонки
  class3    [4] = "text-center";
  style3    [4] = "font-size:45px;font-weight:bold;line-height:2em;height:70px;";

  id        [5] = "55"; // === 5 === Button_Plus
  page      [5] = room;
  pageId    [5] = "52";
  sTopic    [5] = prefdev + "/B_Plus";
  widget    [5] = "simple-btn";
  class1    [5] = "item no-border col-xs-4"; // Размер колонки
  style1    [5] = "text-align: right;";
  class2    [5] = "balanced";
  class3    [5] = "button button-assertive button-fab button-outline icon ion-plus";
  style3    [5] = "height:80px;width:80px;";
  more      [5] = ",\"delay\":\"1000\"";

  id        [6] = "57"; // === 6 === Button_MinusA
  page      [6] = room;
  pageId    [6] = "52";
  sTopic    [6] = prefdev + "/B_MinusA";
  widget    [6] = "simple-btn";
  class1    [6] = "item no-border col-xs-4"; // Размер колонки
  class2    [6] = "balanced";
  class3    [6] = "button button-calm button-fab button-outline icon ion-minus";
  style3    [6] = "height:60px;width:60px;";
  hide      [6] = false;

  id        [7] = "58"; // === 7 === Нагревать с 23 до 7
  page      [7] = room;
  pageId    [7] = "52";
  sTopic    [7] = prefdev + "/setpointA";
  stat      [7] = setStatus(String(setpointA) + "°");
  widget    [7] = "anydata";
  class1    [7] = "item no-border col-xs-4"; // Размер колонки
  class3    [7] = "text-center";
  style3    [7] = "font-size:35px;font-weight:bold;line-height:2em;height:50px;";
  hide      [7] = false;

  id        [8] = "59"; // === 8 === Button_PlusA
  page      [8] = room;
  pageId    [8] = "52";
  sTopic    [8] = prefdev + "/B_PlusA";
  widget    [8] = "simple-btn";
  class1    [8] = "item no-border col-xs-4"; // Размер колонки
  style1    [8] = "text-align: right;";
  class2    [8] = "balanced";
  class3    [8] = "button button-assertive button-fab button-outline icon ion-plus";
  style3    [8] = "height:60px;width:60px;";
  hide      [8] = false;

  id        [9] = "56"; // === 9 === Время
  page      [9] = room;
  pageId    [9] = "52";
  sTopic    [9] = prefdev + "/DateTime";
  stat      [9] = setStatus(String(addZero(day(), 2, " ") + "." + addZero(month(), 2, "0") + "." + addZero(year(), 2, "0") + " " + addZero(hour(), 2, "0") + ":" + addZero(minute(), 2, "0") + ":" + addZero(second(), 2, "0")));
  widget    [9] = "anydata";
  descr     [9] = "Время";
  class1    [9] = "item rounded no-padding";
  style1    [9] = "";
  class2    [9] = "rounded padding";
  style2    [9] = "font-size:15px;float:left;height:50px";
  class3    [9] = "rounded padding";
  style3    [9] = "font-size:15px;text-align:right;height:50px";

  id        [10] = "60"; // === 10 === DS18B20
  page      [10] = room;
  pageId    [10] = "52";
  sTopic    [10] = prefdev + "/DS18B20";
  stat      [10] = setStatus(DS18B20_1S + " °C");
  widget    [10] = "anydata";
  descr     [10] = "Улица";
  class1    [10] = "item rounded no-padding";
  style1    [10] = "";
  class2    [10] = "rounded padding";
  style2    [10] = "font-size:20px;float:left;height:50px";
  class3    [10] = "rounded padding";
  style3    [10] = "font-size:30px;text-align:right;height:50px";

  needPubConfig = true;
}

// send confirmation - status message
void pubStatus(String t, String payload)
{
  client.publish(t + "/status", payload);
  delay(PUB_DELAY);
}

void pubConfig()
{
  needPubConfig = false;
  for (int i = 0; i < nWidgets; i = i + 1)
  {
    pubConfigX(i);
  }
  yield();
}

void pubConfigX(int i)
{
  if (hide[i] == false)
  {
    thing_config[i] = "{\"id\":" + id[i] + ",\"page\":\"" + page[i] + "\",\"pageId\":" + pageId[i] + ",\"widget\":\"" + widget[i] + "\",\"descr\":\"" + descr[i] + "\",\"topic\":\"" + sTopic[i] + "\",\"class1\":\"" + class1[i] + "\",\"style1\":\"" + style1[i] + "\",\"class2\":\"" + class2[i] + "\",\"style2\":\"" + style2[i] + "\",\"class3\":\"" + class3[i] + "\",\"style3\":\"" + style3[i] + "\"" + more[i] + "}";
  }
  else
  {
    thing_config[i] = "{\"id\":" + id[i] + ",\"page\":\"" + page[i] + "\"}";
  }
    client.publish(MQTT::Publish(prefdev + "/config", thing_config[i]).set_qos(1));
    delay(PUB_DELAY);
    pubStatus(sTopic[i], stat[i]);
}

void controlGPIO ()
{
  String t = topic;
  String p = payload;

  needControlGPIO = false;

if (t == sTopic[0] + "/control")      // === 0 === Температура
  {
  }
else if (t == sTopic[1] + "/control") // === 1 === Влажность
  {
  }
else if (t == sTopic[2] + "/control") // === 2 === Нагреватель
  {
    if (p == "0")
    {
      //digitalWrite(Relay_pin, OFF);
      stat[2] = stat0;
      getDHT22();
      for (int i = 3; i < 9; i = i + 1)
      {
        hide[i] = false;
        pubConfigX(i);
      }
    }
    else
    {
      digitalWrite(Relay_pin, ON);
      stat[2] = stat1;
      for (int i = 3; i < 9; i = i + 1)
      {
        hide[i] = true;
        pubConfigX(i);
      }
    }
    pubStatus(sTopic[2], stat[2]);
    chkdRt();
  }
else if (t == sTopic[3] + "/control") // === 3 === Button_Minus
  {
    setpointMinus();
  }
else if (t == sTopic[4] + "/control") // === 4 === setpoint
  {
  }
else if (t == sTopic[5] + "/control") // === 5 === Button_Plus
  {
    setpointPlus();
  }
else if (t == sTopic[6] + "/control") // === 6 === Button_MinusA
  {
    setpointMinusA();
  }
else if (t == sTopic[7] + "/control") // === 7 === Нагревать с 23 до 7
  {
  }
else if (t == sTopic[8] + "/control") // === 8 === Button_PlusA
  {
    setpointPlusA();
  }
else if (t == sTopic[9] + "/control") // === 9 === Время
  {
  }
else if (t == sTopic[10] + "/control") // === 10 === DS18B20
  {
  }
}

// ========================== publish =========================================================

  if( count10 < 10)
  {
    count10 ++;
  }
  else
  {
    pubStatus(sTopic[0], "{\"status\":\"" + DHT22_tS + " °C\"}");
    pubStatus(sTopic[1], "{\"status\":\"" + DHT22_hS + "  %\"}");
  stat[4] = setStatus(String(addZero(setpoint, 2, " ")) + "°"); // === Статус регулятора Нагревателя
    pubStatus(sTopic[4], stat[4]);
  stat[9] = setStatus(String(addZero(day(), 2, " ") + "." + addZero(month(), 2, "0") + "." + addZero(year(), 2, "0") + " " + addZero(hour(), 2, "0") + ":" + addZero(minute(), 2, "0") + ":" + addZero(second(), 2, "0")));
    pubStatus(sTopic[9], stat[9]); // Дата и Время
    pubStatus(sTopic[10], "{\"status\":\"" + DS18B20_1S + " °C\"}");
    count10 = 0;
  }
      client.loop();
    }
  }
  else
  {
        delay(1000);
  }
}

String setStatus ( String s )
{
  String stat = "{\"status\":\"" + s + "\"}";
  return stat;
}
String setStatus ( int s )
{
  String stat = "{\"status\":\"" + String(s) + "\"}";
  return stat;
}
 

roiksv

Member
А так к выкрутасам добавится стандартный вариант без увеличения кода в девайсе. Конечно хотеть одно-реализовать другое.
 

Mоnk

Member
"class of restrict"...
Очень глобально. Показывать или прятать группу виджетов в зависимости от чего-либо? Не уверен, что это жизненно необходимо. Пустой / не пустой конфиг вполне себе работает.
 

roiksv

Member
Нужно-не нужно. Вы скрываете-показываете что-либо, значит есть необходимость. Просто скажу иначе: сейчас мой планшет отображает информацию непонятно как. При открытии программы происходит путаница в строках, приходится передергивать экран. Увеличивая количество девайсов увеличивается объем выводимой информации. Пользователей может быть не один, скрыли-показали топики и забыли. Соответственно появляются лишние телодвижения для получения нужной информации. Я уже не говорю о том, что усложняется код на девайсе. Что не очень дружелюбно для нового пользователя
 

Victor

Administrator
Команда форума
Пользователей может быть не один
1.можно раздавать разные конфиги разным устройствам и/или пользователям - для этого есть [inline]user[/inline], [inline]users[/inline] [inline]uuid[/inline] Виджет anydata · IoT Manager
2. ненужные (в данный момент) виджеты можно перемещать на отдельную страницу
3. просто слать разные конфиги, в зависимости от принятых данных (т.е. делаете виджеты [inline]simple-btn[/inline] и отсылаете команды устройству, а он в ответ шлет другие конфиги, в зависимости от нажатой кнопки)
 

roiksv

Member
Victor, я это все понимаю. Просто хотелось получить простой механизм для скрытия-показа информации. Без лишних телодвижений (писанины кода прошивки, нажатия кнопок и т.п.). Скажу больше, в один прекрасный момент умный дом может остаться без умного хозяина. Для этих случаев писать толмут как пользоваться: это нажми, то не нажимай. Я предложил как на мой взгляд простое решение. Теперь решение за автором
 

Victor

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

roiksv

Member
Ну не знаю, что может быть проще чем указать в прошивке sTopic[0] = prefix + "/" + deviceID + "/setup/light" и в проге выставить уровень отображения 2, и не видеть данные этого топика. Ситуация: автора умного дома нет в зоне досягаемости, настроен показ виджета по юзеру. Жена теперь должна догадаться какой там был у хозяина доступ, перелогиниться и изменить настройку чего-либо. Моя жена этого делать не будет, вырубит нафиг всю автоматику в доме. Короче говоря, или я, как начинающий пользователь чего-то не понимаю, или лыжи не едут. Насчет протокола v2-посмотрю
 
Последнее редактирование:

Victor

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

roiksv

Member
@Victor, т.к дискуссия развязалась здесь, а не в "хотелке", я не стал говорить о скрытой стороне моей "хотелки" (т.е мне было бы проще дальше реализовать свой проект). Привел только доводы, как мне думалось, которые могли еще кого-то заинтересовать. Я придумал костыль. Поэтому вопрос исчерпан)).
 

oWart

New member
@Victor, не знаю, может это косяк библиотеки Paho, т.к это относится к уровню самого протокола MQTT, но все же напишу: топик /IoTmanager/device приходит в таком виде:
30 98 01 00 12 2F 49 6F 54 6D 61 6E 61 67 65 72 2F 64 65 76 69 63 65 7B 22 63 .... и.т.д
Согласно спецификации v.3.1.1 байты 3 и 4 это длина имени топика (Length MSB и LSB). Отсюда получается, что длина имени топика 256 символов, хотя длина всего сообщения 152 байта (Remaining Length = 98h).
 

Victor

Administrator
Команда форума
может это косяк библиотеки Paho
Если Paho Websockets, то вряд ли, он протестирован миллионы раз. На гитхабе о такой ошибке другие пользователи не сообщают... Нужно искать причину в другом. Если используете [inline]paho native[/inline], то попробуйте убить IoT Manager (любым Task Manager) и снова запустить - за нативным движком я иногда замечал подглючивание пока не перезапустишь. Было бы любопытно узнать подробности (версии брокера, SSL есть/нет и т.п.)
 

oWart

New member
@Victor, пишу свой упрощенный брокер на esp8266 на библиотеке WebSocket, без SSL. Все остальные сообщения корректны, а это принимается с такой вот длиной топика
 

Victor

Administrator
Команда форума
Посмотрите документацию - там приличного размера пакет прилетает после [inline]HELLO[/inline] в [inline]prefix + "/device"[/inline]
свой упрощенный брокер на esp8266 на библиотеке WebSocket
ок, может и потянет ESP8266 небольшой трафик. Только вот сколько получится одновременных коннектов держать?
В любом случае - удачи!
 

Mainscs

Member
В связи с появлением новых стилей оформления - dark и обычных, может быть стоит для виджета display-value предусмотреть режим без отображения неактивных сегментов (inactive_color) - т.е. сделать их прозрачными. Иначе возможна ситуация, когда виджет настроен на стиль dark, и, соответственно, неактивные сегменты по цвету близки к черному. При переходе к светлому стилю неактивные сегменты выглядят как черные на белом фоне. Возможна и обратная картина.
 
Сверху Снизу