ESP, IoT [BigClock] Большие часы на WS2812, ESP8266, Народный мониторинг

Какой вариант датчика используется у вас? Интересно, использует ли кто BME280, как у меня?)

  • BMP280

    Голосов: 26 26.8%
  • BME280

    Голосов: 71 73.2%

  • Всего проголосовало
    97

Leon111_09

★★★✩✩✩✩
6 Июн 2021
641
150
56
Таганрог
forum.wisecomp.ru
Не надо постоянно долбить сервера NTP
Почему? Я в другом проекте (там только вемос и олед из железа были,простенький проект) использовал сервер ru.pool.ntp.org (и в этом использую). Так в том проекте запрос отправлялся два раза в минуту.Нормально проработал почти год без выключения,никто не банил.Время и дата всегда были самыми точными.
 

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
блин . что то не пойму часы дома работали снял привез на работу и все на этом . вопрос такой если у часов нет соединения по вайфай сами диоды загореца должныже ?
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@wulf, если нет сети, то должна через некоторое время стартануть точка доступа. Часы по идее должны запустится, только что покажут, не знаю. Если есть rtc, то время пойдет с них.
 

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
@ASM,rtc нет . да точка запускалась но почему то по 192.168.4.1 я не смог зайти чтоб забить параметры точки и часы даже не загорелись пришлось качать снова все библиотеки и прошивать ток потом запустились
 

AndrF

✩✩✩✩✩✩✩
4 Апр 2023
11
1
@wulf, если нет сети, то должна через некоторое время стартануть точка доступа. Часы по идее должны запустится, только что покажут, не знаю. Если есть rtc, то время пойдет с них.
В качестве резервного питания для RTC я использую ионистор. На пару недель его вполне хватает - больше не пробовал...
 

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
@AndrF,я вообще хочу 18650 туда прилепить чтоб без провадов юзать
 

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
я конечно понимаю что проще заказать сразу герметичные датчики но уже поздно едут обычные . может кто подскажет как правильно сделать есть медная трубка вот думаю засунуть в нее датчик да запаять вот ток не знаю нужно или нет чтоб межу датчиком и трубкой был зазор или чтобы они контактировали между собой

что подскажите ?
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@wulf, можешь заказать герметичный, потом заменишь. На сезон точно хватит и обычного, на улице. Или если не жалко, можешь взять на WB, за 184р нашел.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Обновлена библиотека GyverPortal, в ней исправлена проблема с точкой доступа на некоторых устройствах. Тут жаловались, что не стартует, проверяйте)
 

Leon111_09

★★★✩✩✩✩
6 Июн 2021
641
150
56
Таганрог
forum.wisecomp.ru
@ASM, Я сегодня зарегистрировался на народном мониторе.В качестве ребералки указал вашу тему с часами-надеюсь,вам там какие нибудь бонусы капнут :)
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Leon111_09, бонусы, по сути увеличение количества приборов) за стаж и публичные датчики)
У меня этот основной, с матрицей в тесте, не публичен, не в сети и ещё прибор доступен) вот и все бонусы)

Ник в мониторинге аналогичен этому)

п.с. посмотрите новый ролик у Алекса)
 
Изменено:
  • Лойс +1
Реакции: Glock12

Leon111_09

★★★✩✩✩✩
6 Июн 2021
641
150
56
Таганрог
forum.wisecomp.ru
п.с. посмотрите новый ролик у Алекса
Уже посмотрел :).
У меня к вам вопрос. В последней прошивке в одном месте код продублирован:

Код:
#define MP3_RX_PIN 2               //GPIO2/D4 к DFPlayer Mini TX
#define MP3_TX_PIN 16              //GPIO16/D0 к DFPlayer Mini RX
#define MP3_SERIAL_SPEED 9600      //DFPlayer Mini поддерживает только 9600 бод
#define MP3_SERIAL_BUFFER_SIZE 32  //размер последовательного буфера программного обеспечения в байтах, для отправки 8 байтов вам нужен 11-байтовый буфер (стартовый байт + 8 битов данных + байт четности + стоп-байт = 11 байтов)
#define MP3_SERIAL_TIMEOUT 350     //среднее время ожидания ответа DFPlayer для чипа GD3200B 350 мс..400 мс

//Настройки для DFPlayer
#define MP3_RX_PIN 2               //GPIO2/D4 к DFPlayer Mini TX
#define MP3_TX_PIN 16              //GPIO16/D0 к DFPlayer Mini RX
#define MP3_SERIAL_SPEED 9600      //DFPlayer Mini поддерживает только 9600 бод
#define MP3_SERIAL_BUFFER_SIZE 32  //размер последовательного буфера программного обеспечения в байтах, для отправки 8 байтов вам нужен 11-байтовый буфер (стартовый байт + 8 битов данных + байт четности + стоп-байт = 11 байтов)
#define MP3_SERIAL_TIMEOUT 350     //среднее время ожидания ответа DFPlayer для чипа GD3200B 350 мс..400 мс

Так и должно быть? Эти куски полностью идентичны и идут друг за другом.
И попутно еще второй вопрос: как думаете,для проекта можно использовать ESP-01? Там максимум 1 Мбайт памяти.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Leon111_09, если это так, то банальная копипаст, почищу) странно, что компилятор ничего не сообщил)
ESP-01, не силён в этой теме, но думаю работать должно. Только прошивать сложнее) Что напишут спецы, подождём...
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
C++:
К сожалению, как AI модель, я не способен написать код. Однако, я могу предложить вам базовый код для использования адресной светодиодной ленты на Arduino для создания часов:

```

#include <FastLED.h>

#define LED_PIN 6   // укажите здесь номер пина, к которому подключена LED-лента

#define LED_COUNT 60  // количество светодиодов в ленте

#define BRIGHTNESS 80  // уровень яркости LED-ленты

CRGB leds[LED_COUNT]; // массив для хранения значений цвета светодиодов

int currentMinute; // переменная текущей минуты

int currentHour; // переменная текущего часа

void setup() {

  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, LED_COUNT); // настройка LED-ленты

  FastLED.setBrightness(BRIGHTNESS); // установка яркости

  // получаем первоначальное значение времени

  currentMinute = minute();

  currentHour = hour();

}

void loop() {

  // получаем текущее время

  currentMinute = minute();

  currentHour = hour();

  // вычисляем позицию текущей минуты и устанавливаем соответствующий цвет

  int minutePosition = map(currentMinute, 0, 59, 0, LED_COUNT);

  leds[minutePosition] = CRGB::Green;

  // вычисляем позицию текущего часа и устанавливаем соответствующий цвет

  int hourPosition = map(currentHour % 12, 0, 11, 0, LED_COUNT);

  leds[hourPosition] = CRGB::Red;

  // отправляем данные на LED-ленту

  FastLED.show();

  // очищаем массив светодиодов для следующей итерации

  fill_solid(leds, LED_COUNT, CRGB::Black);

  // ждем 1 секунду

  delay(1000);

}

```

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

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
@ASM, помниш кидал там где цифры переливаются попросил нейросеть оптимизировать это
C++:
void clockColor() {

  int8_t color_idx = 0;
  switch (thisMode) {
    case MC_CLOCK:
      // Если режим часов включен как "Ночные часы" - цвет определять по настроенному цвету ночных часов
      // Иначе - цвет часов зависит от режима (Монохром, Каждая цифра свой цвет, Цвет часов-точек-минут" и т.д)
      color_idx = isNightClock ? -2 : COLOR_MODE;
      break;
    case MC_COLORS:
    case MC_FILL_COLOR:
      color_idx = -1;
      break;
    default:
      color_idx = COLOR_MODE;
      break;
  }
   
  if (color_idx == -2) {
    // Цвет по индексу настроек текущего ночного цвета    
    CRGB color = getNightClockColorByIndex(nightClockColor);
    for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
  } else if (color_idx == -1) {    
    // Инверсный от основного цвет
    CRGB color = globalColor == 0xFFFFFF
      ? color = CRGB::Navy
      : -CRGB(globalColor);
    for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
  } else if (color_idx == 0) {    
    // Монохромные часы
    uint8_t hue = effectScaleParam[MC_CLOCK];
    CHSV color = hue <= 1 ? CHSV(255, 0, 255): CHSV(hue, 255, 255);
    for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
  } else if (color_idx == 1) {
    // Каждая цифра своим цветом, плавная смена цвета
    for (uint8_t i = 0; i < 5; i++) clockLED[i] = CHSV(clockHue + HUE_GAP * i, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
  } else if (color_idx == 2) {
    // Часы, точки, минуты своим цветом, плавная смена цвета
    clockLED[0] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[1] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
    clockLED[3] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
    clockLED[4] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
  } else {
    CRGB color = getGlobalClockColor();
    for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
  }
}
  1. Убрать дублирующийся код. В каждом блоке условия присваивается цвет, можно вынести его за пределы блока и использовать общую переменную:
C++:
CRGB color;
if (color_idx == -2) {    
    color = getNightClockColorByIndex(nightClockColor);
} else if (color_idx == -1) {    
    color = globalColor == 0xFFFFFF
      ? color = CRGB::Navy
      : -CRGB(globalColor);
} else if (color_idx == 0) {    
    uint8_t hue = effectScaleParam[MC_CLOCK];
    color = hue <= 1 ? CHSV(255, 0, 255) : CHSV(hue, 255, 255);
} else if (color_idx == 1) {
    color = CHSV(clockHue + HUE_GAP * i, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255);
} else if (color_idx == 2) {    
    clockLED[0] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[1] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255);
    clockLED[3] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
    clockLED[4] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
} else {
    color = getGlobalClockColor();
}

for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
  1. Избавиться от магических чисел. Можно задать константы для условий:
C++:
const int8_t NIGHT_MODE_COLOR = -2;
const int8_t INVERT_COLOR = -1;
const int8_t MONOCHROME_COLOR = 0;
const int8_t EACH_NUMBER_COLOR = 1;
const int8_t HOUR_MINUTE_COLOR = 2;
и заменить условия в соответствующих местах на константы:
C++:
if (color_idx == NIGHT_MODE_COLOR) {    
    color = getNightClockColorByIndex(nightClockColor);
} else if (color_idx == INVERT_COLOR) {    
    color = globalColor == 0xFFFFFF
      ? color = CRGB::Navy
      : -CRGB(globalColor);
} else if (color_idx == MONOCHROME_COLOR) {    
    uint8_t hue = effectScaleParam[MC_CLOCK];
    color = hue <= 1 ? CHSV(255, 0, 255) : CHSV(hue, 255, 255);
} else if (color_idx == EACH_NUMBER_COLOR) {
    color = CHSV(clockHue + HUE_GAP * i, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255);
} else if (color_idx == HOUR_MINUTE_COLOR) {    
    clockLED[0] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[1] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
    clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255);
    clockLED[3] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
    clockLED[4] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
} else {
    color = getGlobalClockColor();
}
  1. Упростить условие с INVERT_COLOR. В блоке условия задается дважды значение в качестве color, можно его убрать:
C++:
if (color_idx == INVERT_COLOR) {    
    color = globalColor == 0xFFFFFF
      ? CRGB::Navy
      : -CRGB(globalColor);
} else {
    // Присваивание цвета..
}

попросил оптимизировать этот код чтобы работал вместо твоего то выдал это
C++:
void clockColor() {

int8_t color_idx = 0;
switch (thisMode) {
case MC_CLOCK:
// Если режим часов включен как "Ночные часы" - цвет определять по настроенному цвету ночных часов
// Иначе - цвет часов зависит от режима (Монохром, Каждая цифра свой цвет, Цвет часов-точек-минут" и т.д)
color_idx = isNightClock ? -2 : COLOR_MODE;
break;
case MC_COLORS:
case MC_FILL_COLOR:
color_idx = -1;
break;
default:
color_idx = COLOR_MODE;
break;
}

if (color_idx == -2) {
// Цвет по индексу настроек текущего ночного цвета

CRGB color = getNightClockColorByIndex(nightClockColor);
for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
} else if (color_idx == -1) {

// Инверсный от основного цвет
CRGB color = globalColor == 0xFFFFFF ? CRGB::Navy : -CRGB(globalColor);
for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;

} else {
if (color_idx == 0) {
// Монохромные часы

uint8_t hue = effectScaleParam[MC_CLOCK];
CHSV color = hue <= 1 ? CHSV(255, 0, 255): CHSV(hue, 255, 255);
for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
} else if (color_idx == 1) {
// Каждая цифра своим цветом, плавная смена цвета
for (uint8_t i = 0; i < 5; i++) clockLED[i] = CHSV(clockHue + HUE_GAP * i, 255, 255);
clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
} else if (color_idx == 2) {
// Часы, точки, минуты своим цветом, плавная смена цвета
clockLED[0] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
clockLED[1] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
clockLED[3] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
clockLED[4] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
} else {
CRGB color = getGlobalClockColor();
for (uint8_t i = 0; i < 5; i++) clockLED[i] = color;
}
}
}

void Digit(uint8_t digit, uint8_t cursor) {  // функция отображения символов
for (uint8_t mask = 0b01000000; mask > 0; mask >>= 1) {
leds[cursor] = (digit & mask) ? (c.new_god ? ColorTable[rand() % NUM_COLORS - 1] : ledColor) : CRGB(0, 0, 0);
cursor += LEDS_IN_SEGMENT;
}
}
но нейра не знает весь код поэтому имеем
exit status 1
'thisMode' was not declared in this scope
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@wulf, без шоколадки не разобраться))
Что-то перемудрено тут)

Вот ещё вариант, вот только интересно, как тут работает map?
Будет ли что-то показывать с таким вариантом, где не описываются символы...
C++:
// Подключаем все библиотеки

#include <ESP8266WiFi.h>

#include <FastLED.h>

// Настройки WiFi

const char* ssid = "название Wi-Fi сети";

const char* password = "пароль от Wi-Fi сети";

// Создаем экземпляр объекта адресной светодиодной ленты

#define LED_PIN D1

#define LED_COUNT 60

CRGB leds[LED_COUNT];

// Функция установки текущего времени

void setTime()

{

  // Подключаемся к интернету

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)

  {

    delay(1000);

    Serial.println("Connecting to WiFi...");

  }

 

  // Запрашиваем время с сервиса NTP

  configTime(0, 0, "pool.ntp.org", "time.nist.gov");

  Serial.println("Waiting for time");

  while (!time(nullptr))

  {

    delay(1000);

  }

}

// Функция отображения времени на светодиодной ленте

void showTime()

{

  // Получаем текущее время

  time_t now = time(nullptr);

  struct tm* timeinfo;

  timeinfo = localtime(&now);

  // Разбиваем время на компоненты (часы, минуты, секунды)

  int hour = timeinfo->tm_hour;

  int minute = timeinfo->tm_min;

  int second = timeinfo->tm_sec;

  // Очищаем ленту светодиодов

  FastLED.clear();

  // Отображаем часы на ленте

  int hourIndex = map(hour, 0, 23, 0, LED_COUNT);

  for (int i = 0; i < hourIndex; i++)

  {

    leds[i] = CRGB::Red;

  }

  // Отображаем минуты на ленте

  int minuteIndex = map(minute, 0, 59, 0, LED_COUNT);

  for (int i = hourIndex; i < minuteIndex; i++)

  {

    leds[i] = CRGB::Green;

  }

  // Отображаем секунды на ленте

  int secondIndex = map(second, 0, 59, 0, LED_COUNT);

  for (int i = minuteIndex; i < secondIndex; i++)

  {

    leds[i] = CRGB::Blue;

  }

  // Отображаем ленту светодиодов

  FastLED.show();

}

// Функция настройки и запуска

void setup()

{

  // Настраиваем последовательный порт

  Serial.begin(9600);

  // Настраиваем светодиодную ленту

  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, LED_COUNT);

  // Устанавливаем текущее время

  setTime();

  // Запускаем таймер для обновления времени и отображения его на ленте

  ticker.attach(1, showTime);

}

// Функция бесконечного цикла

void loop()

{

  // Поскольку мы обновляем время каждую секунду в showTime,

  // функция loop может оставаться пустой

}
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,298
958
попросил нейросеть оптимизировать это
смешно
Запомните - нейросеть может только помочь вам, но не заменять вас. Чтобы пользоваться ИИ, нужно понимать в вопросе (в данном случае в программировании) лучшее робота. Вы должны понимать код настолько, чтобы уметь оценить, правильный ли результат выдал робот или фигню.
Поэтому если вы сами ничего не понимаете в программе - не пытайтесь с помощью ИИ оптимизировать код.

В данном случае в ходе "оптимизации" ИИ вам выкинул из кода те самые "переливы", которые вы пытаетесь добавить :)


Я вообще не понял, нафига тут что-то оптимизировать? Код довольно прост - берем радужное колесо HUE и распределяем цвета символов по нему. Вот и все.
По сути вам нужны только эти строчки
C++:
if (color_idx == 1) {
// Каждая цифра своим цветом, плавная смена цвета
for (uint8_t i = 0; i < 5; i++) clockLED[i] = CHSV(clockHue + HUE_GAP * i, 255, 255);
clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
} else if (color_idx == 2) {
// Часы, точки, минуты своим цветом, плавная смена цвета
clockLED[0] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
clockLED[1] = CHSV(clockHue + HUE_GAP * 0, 255, 255);
clockLED[2] = CHSV(clockHue + 128 + HUE_GAP * 1, 255, 255); // точки делаем другой цвет
clockLED[3] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
clockLED[4] = CHSV(clockHue + HUE_GAP * 2, 255, 255);
}
нужно определить две переменные
clockHue - начальное значение цвета
HUE_GAP - смещение цвета для каждой цифры

Еще нужен массив цветов для цифр clockLED[]
 
Изменено:

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
мне знакомый вот такое по whatsapp скинул вроде все правильно переписал но по моему слишком замудрено


C++:
для создания циферблата с радужной цветовой схемой:

const HUE_GAP = 30; // расстояние между цветами по радужному колесу
let clockHue = 100; // начальный цвет для первой цифры

for (let i = 1; i <= 12; i++) {
let angle = (i - 3) * 30 * Math.PI / 180; // вычисляем угол для размещения цифры
let x = 150 + Math.cos(angle) * 120; // вычисляем координаты на круге для размещения цифры
let y = 150 + Math.sin(angle) * 120;

// создаем элемент span с номером цифры и применяем ему соответствующий цвет
let digit = document.createElement("span");
digit.innerHTML = i;
digit.style.color = hsl(${clockHue}, 70%, 60%);
digit.style.position = "absolute";
digit.style.left = ${x}px;
digit.style.top = ${y}px;
digit.style.fontSize = "3rem";
digit.style.fontWeight = "bold";
digit.style.transform = "translate(-50%, -50%)";
document.body.appendChild(digit);

// увеличиваем значение цвета для следующей цифры
clockHue += HUE_GAP;
}

для создания циферблата с двухцветной схемой:

let clockHue = 100; // начальный цвет для первых двух цифр
let dotHue = 160; // цвет для точек
let lastTwoHue = 190; // цвет для последних двух цифр

for (let i = 1; i <= 12; i++) {
let angle = (i - 3) * 30 * Math.PI / 180;
let x = 150 + Math.cos(angle) * 120;
let y = 150 + Math.sin(angle) * 120;

let digit = document.createElement("span");
digit.innerHTML = i;
digit.style.position = "absolute";
digit.style.left = ${x}px;
digit.style.top = ${y}px;
digit.style.fontSize = "3rem";
digit.style.fontWeight = "bold";
digit.style.transform = "translate(-50%, -50%)";

if (i <= 2) {
digit.style.color = hsl(${clockHue}, 70%, 60%);
} else if (i == 3 || i == 6 || i == 9 || i == 12) {
let dot = document.createElement("span");
dot.innerHTML = "·";
dot.style.color = hsl(${dotHue}, 70%, 60%);
dot.style.position = "absolute";
dot.style.left = ${x}px;
dot.style.top = ${y + 20}px;
dot.style.fontSize = "2rem";
dot.style.fontWeight = "bold";
dot.style.transform = "translate(-50%, -50%)";
document.body.appendChild(dot);
} else if (i <= 4) {
digit.style.color = hsl(${lastTwoHue}, 70%, 60%);
} else {
digit.style.color = hsl(${clockHue}, 70%, 60%);
}

document.body.appendChild(digit);

clockHue += 30;
lastTwoHue += 30;
}
 

wulf

★✩✩✩✩✩✩
1 Дек 2022
198
27
@bort707,да не спорю. он мне скинул как вариант исполнения
 

maksland

★★★✩✩✩✩
13 Янв 2019
617
145
Omsk
платы еще не пришли на новые индикаторы и я что то отстал от темы совсем (уведомления не включил)
какой последний скетч для проверки скачать можно ?
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@maksland, так смотри последний на последних страницах) думаю на выходных опубликую, проблем не вижу)
 

maksland

★★★✩✩✩✩
13 Янв 2019
617
145
Omsk
хорошо, а то хочу тоже на народный мониторинг зайти с вашим скетчем