• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Отправить время в браузер

humaxoid

New member
Приветсвую! На страницу необходимо вывести время. Нашел простой ntp клиент.
Собственно вопрос. Не знаю как в джава скрипт передать данные о времени?

C++:
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 10800;    // GMT+3
const int daylightOffset_sec = 3600;

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    Serial.println("Couldn't get the time");
    return;
  }
  Serial.println(&timeinfo, "%d %B %H:%M:%S");
    
void setup()
{   
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();
}
    
void loop() {
 delay(1000);
 printLocalTime();
}

JavaScript:
document.getElementById("dateTime").innerHTML = test;

В html пологаю будет так.

HTML:
<span id="dateTime"></span>
 

Vovka

Member
Если один раз, перед выводом HTML-странички, то в этой страничке объявите например так:
Код:
var test=<!--TEST-->;
а перед выводом странички делайте поиск-замену "<!--TEST-->"

Если нужно постоянно менять на страничке время, то есть два решения: XMLHttpRequest или WebSocket
 

fps

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

Вот так напишите и получите динамически обновляемое время. Без смс и регистрации ajax и вебсокетов.

HTML:
<span id="dateTime"></span>
JavaScript:
setInterval("document.getElementById('dateTime').innerHTML = Date()", 1000);
 

Vovka

Member
некоторые браузеры, если эта конструкция используется в таблице с одной колонкой, без неразрывного пробела вырезают эту строку! А когда добавляем данные, то строка появляется. В итоге прыгает высота таблицы!
 

fps

Active member
некоторые браузеры
Да вроде нынче кроме хромиумов и фаерфокс больше и нет ничего.

В итоге прыгает высота таблицы!
Это решается не костылями nbsp, а с помощью css :)

И само собой, мой пример - это просто пример. Он хоть и работоспособен, но как есть его использовать никто не станет ведь.
 

Vovka

Member
Да вроде нынче кроме хромиумов и фаерфокс больше и нет ничего.
А родные браузеры мобильных телефонов?
Это решается не костылями nbsp, а с помощью css :)
Для мобильников лучше nbsp, чем вычислять что из css не понимает!
 

humaxoid

New member
Ну да, дополнительный пробел не решает проблемы )) Вопрос был в другом!
У меня вэбсокет вот такой конструкции.
C++:
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

// Replace with your network credentials
const char* ssid = "ssid";
const char* password = "******";

bool ledState = 0;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

void notifyClients() {
  ws.textAll(String(ledState));
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledState = !ledState;
      notifyClients();
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

String processor(const String& var){
  Serial.println(var);
  if(var == "STATE"){
    if (ledState){
      return "ON";
    }
    else{
      return "OFF";
    }
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  pinMode(25, OUTPUT);
  digitalWrite(25, LOW);
 
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  initWebSocket();

  // Инициализируем SPIFFS:
  if (!SPIFFS.begin(true))
  {
  //   Serial.println("При монтировании SPIFFS произошла ошибка");
    return;
  }

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(SPIFFS, "/index.html", "text/html", false, processor); });

  // Start server
  server.begin();
}

void loop() {
  ws.cleanupClients();
  digitalWrite(25, ledState);
}
HTML:
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
 
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
  <div class="topnav">
    <h1>ESP WebSocket Server</h1>
  </div>
  <div class="content">
    <div class="card">
      <h2>Output - GPIO 2</h2>
      <p class="state">state: <span id="state">%STATE%</span></p>
      <p><button id="button" class="button">Toggle</button></p>
    </div>
  </div>
</body>
</html>
JavaScript:
  var gateway = `ws://${window.location.hostname}/ws`;
  var websocket;
  window.addEventListener('load', onLoad);
  function initWebSocket() {
    console.log('Trying to open a WebSocket connection...');
    websocket = new WebSocket(gateway);
    websocket.onopen    = onOpen;
    websocket.onclose   = onClose;
    websocket.onmessage = onMessage;
  }
  function onOpen(event) {
    console.log('Connection opened');
  }
  function onClose(event) {
    console.log('Connection closed');
    setTimeout(initWebSocket, 2000);
  }
  function onMessage(event) {
    var state;
    if (event.data == "1"){
      state = "ON";
    }
    else{
      state = "OFF";
    }
    document.getElementById('state').innerHTML = state;
  }
  function onLoad(event) {
    initWebSocket();
    initButton();
  }
  function initButton() {
    document.getElementById('button').addEventListener('click', toggle);
  }
  function toggle(){
    websocket.send('toggle');
  }
setInterval("document.getElementById('dateTime').innerHTML = Date()", 1000);
Так он не будет время тащить с ntp сервера. Скажем если я в будущем прикручу таймеры, мне нужна будет переодическая синхронизация времени.
 

fps

Active member
Так он не будет время тащить с ntp сервера.
мне нужна будет переодическая синхронизация времени.
А причем тут вообще js и вебсокеты тогда?
Если надо время синхронизировать - используйте NTP, он для того и придуман.
 

humaxoid

New member
А причем тут вообще js и вебсокеты тогда?
Если надо время синхронизировать - используйте NTP, он для того и придуман.
Ну так я об этом с самого начала и говорил. Первый код и есть ntp клиент! Вебсокет, отличное решение что бы вывести время на страничку. А без js вообще никак! Любые динамические изменения голым html не выполнить. Можно из loop в js отправить, но это не самое лучшее решение т.к loop в цикле. Если там еще delay крутится, дело ваааще труба. Оно мне надо? Тем более есть действующий вэбсокет.
 

pvvx

Активный участник сообщества
У ntp и передаваемое время в формате linux (в секундах от 1970.01.01) ?
JavaScript:
  let dt = new Date(devtime*1000);
  console.log('Device Date: '+(dt.toISOString().slice(0, -1)).replace('T',' '));
Будет выведено как "Device Date: 2022-02-19 00:08:00.000"
В UTC или Local?
JavaScript:
  let time = Date.now()/1000;
  time -= (new Date()).getTimezoneOffset() * 60;
 
Сверху Снизу