|

Mostrar los valores de varios DS18B20 en un servidor web con ESP8266 NodeMCU

Tutorial de servidor web con ESP8266 para mostrar los valores de varios sensores de temperatura DS18B20

¿Alguna vez has querido tener sensores repartidos por toda tu casa y tu jardín informando su temperatura periódicamente a un servidor central? Entonces, ¡este proyecto de IoT puede ser un excelente punto de partida para ti!

Este proyecto utiliza el ESP8266 NodeMCU como dispositivo de control, que se conecta fácilmente a una red WiFi existente y crea un servidor web. Cuando cualquier dispositivo conectado accede a este servidor web, el ESP8266 lee la temperatura de varios sensores de temperatura DS18B20 y la envía al navegador web de ese dispositivo con una interfaz agradable. ¿Emocionado? ¡Comencemos!

Varios DS18B20 en un solo bus

Una de las mayores ventajas del DS18B20 es que varios DS18B20 pueden coexistir en el mismo bus 1-Wire. Como cada DS18B20 tiene un código serie único de 64 bits grabado de fábrica, resulta más fácil diferenciarlos entre sí.

Esta característica puede ser una enorme ventaja cuando quieres controlar muchos DS18B20 distribuidos en una zona amplia. En este tutorial vamos a hacer exactamente eso.

Cableado de varios sensores DS18B20 al ESP8266 NodeMCU

Conectar los sensores DS18B20 al ESP8266 NodeMCU es bastante sencillo.

Distribución de pines del DS18B20

Empieza conectando todos los DS18B20 en paralelo, es decir, une todos los pines VDD, los pines GND y los pines de señal. Luego conecta VDD a la salida de 3.3V, GND a tierra y conecta el pin de señal al pin digital D2 del ESP8266 NodeMCU.

A continuación, necesitarás añadir una resistencia pull-up de 4.7k para todo el bus, entre el pin de señal y el de alimentación, para mantener estable la transferencia de datos.

Cableado de varios sensores de temperatura DS18B20 al ESP8266
Cableado de varios sensores de temperatura DS18B20 al ESP8266

Preparación del IDE de Arduino

Existe un complemento para el IDE de Arduino que te permite programar el ESP8266 NodeMCU usando el IDE de Arduino. Sigue el tutorial de abajo para preparar tu IDE de Arduino y que funcione con el ESP8266, si aún no lo has hecho.

Tutorial de programación del ESP32 en el IDE de Arduino

Conoce a fondo las características del ESP8266 NodeMCU y cómo usarlo con el IDE de ArduinoEl Internet de las cosas (IoT) ha sido un campo en tendencia en el mundo de la tecnología. Ha cambiado la forma en que trabajamos. Los objetos físicos y…

Instalación de la librería para el DS18B20

El protocolo Dallas 1-Wire es algo complejo y requiere una buena cantidad de código para interpretar la comunicación. Para ocultar esta complejidad innecesaria, instalaremos la librería  DallasTemperature.h  de modo que podamos enviar comandos sencillos para obtener las lecturas de temperatura del sensor.

Para instalar la librería, ve a Arduino IDE > Sketch > Include Library > Manage Libraries… Espera a que el Gestor de Librerías descargue el índice de librerías y actualice la lista de librerías instaladas.

Filtra tu búsqueda escribiendo «ds18b20». Deberían aparecer un par de entradas. Busca DallasTemperature de Miles Burton. Haz clic en esa entrada y luego selecciona Instalar.

Instalación de la librería Dallas Temperature en el IDE de Arduino

Esta librería Dallas Temperature es una librería específica del hardware que gestiona las funciones de más bajo nivel. Necesita combinarse con la librería One Wire para comunicarse con cualquier dispositivo 1-Wire, no solo con el DS18B20. Instala también esta librería.

Instalación de la librería OneWire en el IDE de Arduino

Localización de las direcciones de los DS18B20 en el bus

Sabemos que cada DS18B20 tiene asignada una dirección única de 64 bits para diferenciarlos entre sí. Primero, encontraremos esa dirección para etiquetar cada sensor según corresponda. La dirección se puede usar luego para leer cada sensor de forma individual.

El siguiente sketch detecta todos los DS18B20 presentes en el bus e imprime su dirección 1-Wire en el monitor serie.

Puedes conectar un solo sensor a la vez para encontrar su dirección (o ir añadiendo un nuevo sensor sucesivamente) de modo que puedas identificar cada uno por su dirección. Luego, puedes etiquetar cada sensor.

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port D2 on the ESP8266
#define ONE_WIRE_BUS D2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// variable to hold device addresses
DeviceAddress Thermometer;

int deviceCount = 0;

void setup(void)
{
  // start serial port
  Serial.begin(115200);

  // Start up the library
  sensors.begin();

  // locate devices on the bus
  Serial.println("Locating devices...");
  Serial.print("Found ");
  deviceCount = sensors.getDeviceCount();
  Serial.print(deviceCount, DEC);
  Serial.println(" devices.");
  Serial.println("");

  Serial.println("Printing addresses...");
  for (int i = 0;  i < deviceCount;  i++)
  {
    Serial.print("Sensor ");
    Serial.print(i+1);
    Serial.print(" : ");
    sensors.getAddress(Thermometer, i);
    printAddress(Thermometer);
  }
}

void loop(void)
{ }

void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    Serial.print("0x");
    if (deviceAddress[i] < 0x10) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
    if (i < 7) Serial.print(", ");
  }
  Serial.println("");
}

Ahora, abre el monitor serie. Deberías obtener algo parecido a lo siguiente.

Localización de la dirección 1-Wire de todos los DS18B20 en el bus

Copia todas las direcciones, ya que las necesitaremos en nuestro siguiente sketch.

Crear un servidor web ESP8266 en modo Estación (STA)

Ahora vamos a configurar nuestro ESP8266 en modo Estación (STA) y a crear un servidor web para servir páginas web a cualquier cliente conectado dentro de la red existente.

Si quieres aprender a crear un servidor web con el ESP8266 NodeMCU en modo AP/STA, echa un vistazo a este tutorial.

Creación de un servidor web ESP8266 sencillo en el IDE de Arduino usando el modo Punto de Acceso y Estación

Crear un servidor web sencillo con el ESP8266 NodeMCU en el IDE de ArduinoEn los últimos años, el ESP8266 se ha convertido en una estrella en ascenso entre los proyectos de IoT o relacionados con WiFi. Es un módulo WiFi extremadamente económico que -…

Antes de subir el sketch, necesitas hacer algunos cambios para que funcione en tu caso.

  • Necesitas modificar las dos variables siguientes con las credenciales de tu red, de modo que el ESP8266 pueda establecer una conexión con la red existente.const char* ssid = "YourNetworkName"; // Enter SSID here const char* password = "YourPassword"; //Enter Password here
  • Antes de servir una página web, el ESP8266 lee la temperatura de cada DS18B20 por su dirección, así que necesitas cambiar las direcciones de los DS18B20 por las que encontraste en el sketch anterior.uint8_t sensor1[8] = { 0x28, 0xEE, 0xD5, 0x64, 0x1A, 0x16, 0x02, 0xEC }; uint8_t sensor2[8] = { 0x28, 0x61, 0x64, 0x12, 0x3C, 0x7C, 0x2F, 0x27 }; uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6 };

Una vez que hayas terminado, adelante y prueba el sketch.

#include <ESP8266WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port D2 on the ESP8266
#define ONE_WIRE_BUS D2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float tempSensor1, tempSensor2, tempSensor3;

uint8_t sensor1[8] = { 0x28, 0xEE, 0xD5, 0x64, 0x1A, 0x16, 0x02, 0xEC  };
uint8_t sensor2[8] = { 0x28, 0x61, 0x64, 0x12, 0x3C, 0x7C, 0x2F, 0x27  };
uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6  };

/*Put your SSID & Password*/
const char* ssid = "YourNetworkName";  // Enter SSID here
const char* password = "YourPassword";  //Enter Password here

ESP8266WebServer server(80);

void setup() {
  Serial.begin(115200);
  delay(100);

  sensors.begin();

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

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
}

void handle_OnConnect() {
  sensors.requestTemperatures();
  tempSensor1 = sensors.getTempC(sensor1); // Gets the values of the temperature
  tempSensor2 = sensors.getTempC(sensor2); // Gets the values of the temperature
  tempSensor3 = sensors.getTempC(sensor3); // Gets the values of the temperature
  server.send(200, "text/html", SendHTML(tempSensor1,tempSensor2,tempSensor3));
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(float tempSensor1,float tempSensor2,float tempSensor3){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>ESP8266 Temperature Monitor</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
  ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<div id=\"webpage\">\n";
  ptr +="<h1>ESP8266 Temperature Monitor</h1>\n";
  ptr +="<p>Living Room: ";
  ptr +=tempSensor1;
  ptr +="°C</p>";
  ptr +="<p>Bedroom: ";
  ptr +=tempSensor2;
  ptr +="°C</p>";
  ptr +="<p>Kitchen: ";
  ptr +=tempSensor3;
  ptr +="°C</p>";
  ptr +="</div>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

Acceso al servidor web

Después de subir el sketch, abre el Monitor Serie a una velocidad de 115200 baudios. Y presiona el botón RST del NodeMCU. Si todo está bien, mostrará la dirección IP dinámica obtenida de tu router y mostrará el mensaje HTTP server started.

Dirección IP del servidor web ESP8266 en modo Estación en el Monitor Serie

A continuación, abre un navegador y apúntalo a la dirección IP que se muestra en el monitor serie. El ESP8266 debería servir una página web que muestra las temperaturas de todos los DS18B20.

Múltiples lecturas de DS18B20 en el servidor web ESP32 - Sin CSS

Explicación detallada del código

El sketch comienza incluyendo las siguientes librerías.

  • La librería ESP8266WebServer.h proporciona los métodos WiFi específicos del ESP8266 que llamamos para conectarnos a la red. También tiene algunos métodos disponibles que nos ayudarán a configurar un servidor y manejar las solicitudes HTTP entrantes sin necesidad de preocuparnos por los detalles de implementación de bajo nivel.
  • La librería DallasTemperature.h es una librería específica del hardware que gestiona las funciones de más bajo nivel. Necesita combinarse con la librería One Wire para que funcione.
  • La librería OneWire.h se comunica con cualquier dispositivo 1-Wire, no solo con el DS18B20.
#include <ESP8266WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>

A continuación, creamos las instancias necesarias para el sensor de temperatura y las variables para almacenar las lecturas de temperatura.  El sensor de temperatura está conectado al GPIO D2.

// Data wire is plugged into port D2 on the ESP8266
#define ONE_WIRE_BUS D2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float tempSensor1, tempSensor2, tempSensor3;

A continuación, introducimos las direcciones que encontramos previamente para cada sensor de temperatura.  En nuestro caso, tenemos las siguientes.

uint8_t sensor1[8] = { 0x28, 0xEE, 0xD5, 0x64, 0x1A, 0x16, 0x02, 0xEC  };
uint8_t sensor2[8] = { 0x28, 0x61, 0x64, 0x12, 0x3C, 0x7C, 0x2F, 0x27  };
uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6  };

Como estamos configurando el ESP8266 en modo Estación (STA), se unirá a la red WiFi existente. Por lo tanto, necesitamos proporcionarle el SSID y la contraseña de tu red. A continuación, iniciamos el servidor web en el puerto 80.

/*Put your SSID & Password*/
const char* ssid = "YourNetworkName";  // Enter SSID here
const char* password = "YourPassword";  //Enter Password here

ESP8266WebServer server(80);

Dentro de la función Setup()

Dentro de la función Setup() configuramos nuestro servidor HTTP antes de ejecutarlo realmente. En primer lugar, inicializamos la comunicación serie con la PC e inicializamos el objeto DallasTemperature usando la función begin(). Esta inicializa el bus y detecta todos los DS18B20 presentes en él. A cada sensor se le asigna entonces un índice y se establece la resolución de bits en 12 bits.

Serial.begin(115200);
delay(100);

sensors.begin(); 

Ahora, necesitamos unirnos a la red WiFi usando la función WiFi.begin(). La función toma como parámetros el SSID (nombre de la red) y la contraseña.

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

//connect to your local wi-fi network
WiFi.begin(ssid, password);

Mientras el ESP8266 intenta conectarse a la red, podemos comprobar el estado de la conectividad con la función WiFi.status().

//check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }

Una vez que el ESP8266 está conectado a la red, el sketch imprime la dirección IP asignada al ESP8266 mostrando el valor de WiFi.localIP() en el monitor serie.

Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

Para manejar las solicitudes HTTP entrantes, necesitamos especificar qué código ejecutar cuando se accede a una URL. Para ello, usamos el método on. Este método toma dos parámetros. El primero es una ruta de URL y el segundo es el nombre de la función que queremos ejecutar cuando se accede a esa URL.

El código de abajo indica que cuando un servidor recibe una solicitud HTTP en la ruta raíz (/), activará la función handle_OnConnect. Ten en cuenta que la URL especificada es una ruta relativa.

server.on("/", handle_OnConnect);

No hemos especificado qué debe hacer el servidor si el cliente solicita alguna URL distinta a la especificada con server.on. Debería responder con un estado HTTP 404 (No Encontrado) y un mensaje para el usuario. Ponemos esto también en una función y usamos server.onNotFound para indicarle que debe ejecutarla cuando reciba una solicitud de una URL que no se especificó con server.on

server.onNotFound(handle_NotFound);

Ahora, para iniciar nuestro servidor, llamamos al método begin sobre el objeto server.

server.begin();
Serial.println("HTTP server started");

Dentro de la función Loop()

Para manejar las solicitudes HTTP entrantes reales, necesitamos llamar al método handleClient() sobre el objeto server.

server.handleClient();

A continuación, necesitamos crear la función que adjuntamos a la URL raíz (/) con server.on. ¿Recuerdas?

Al inicio de esta función, obtenemos la lectura de temperatura de cada sensor. Para responder a la solicitud HTTP, usamos el método send. Aunque el método puede llamarse con un conjunto de argumentos diferente, su forma más simple consiste en el código de respuesta HTTP, el tipo de contenido y el contenido.

En nuestro caso, estamos enviando el código 200 (uno de los códigos de estado HTTP), que corresponde a la respuesta OK. Luego, especificamos el tipo de contenido como «text/html» y, por último, llamamos a la función personalizada SendHTML() que crea una página HTML dinámica que contiene las lecturas de temperatura.

void handle_OnConnect() {
  sensors.requestTemperatures();
  tempSensor1 = sensors.getTempC(sensor1);
  tempSensor2 = sensors.getTempC(sensor2);
  tempSensor3 = sensors.getTempC(sensor3);
  server.send(200, "text/html", SendHTML(tempSensor1,tempSensor2,tempSensor3));
}

Del mismo modo, necesitamos crear una función para manejar la página de Error 404.

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

Mostrar la página web HTML

La función SendHTML()  es la responsable de generar una página web cada vez que el servidor web ESP8266 recibe una solicitud de un cliente web. Simplemente concatena código HTML en una cadena grande y lo devuelve a la función server.send() que comentamos antes. La función toma las lecturas de temperatura como parámetro para generar dinámicamente el contenido HTML.

El primer texto que siempre debes enviar es la declaración <!DOCTYPE> que indica que estamos enviando código HTML.

String SendHTML(float tempSensor1,float tempSensor2,float tempSensor3){
  String ptr = "<!DOCTYPE html> <html>\n";

A continuación, el elemento <meta> viewport hace que la página web sea adaptable en cualquier navegador web, mientras que la etiqueta title establece el título de la página.

ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Temperature Monitor</title>\n";

Dar estilo a la página web

A continuación, tenemos algo de CSS para dar estilo a la apariencia de la página web. Elegimos la fuente Helvetica, definimos que el contenido se muestre como un bloque en línea (inline-block) y alineado al centro.

ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";

El siguiente código establece luego el color, la fuente y el margen alrededor de las etiquetas body, H1 y p.

ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";

Establecer el encabezado de la página web

A continuación, se establece el encabezado de la página web; puedes cambiar este texto por cualquier cosa que se adapte a tu aplicación.

ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 Temperature Monitor</h1>\n";

Mostrar las lecturas de temperatura en la página web

Para mostrar dinámicamente las lecturas de temperatura, colocamos esos valores en la etiqueta de párrafo. Para mostrar el símbolo de grados, usamos la entidad HTML &deg;

ptr +="<p>Living Room: ";
ptr +=tempSensor1;
ptr +="°C</p>";
ptr +="<p>Bedroom: ";
ptr +=tempSensor2;
ptr +="°C</p>";
ptr +="<p>Kitchen: ";
ptr +=tempSensor3;
ptr +="°C</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}

Dar estilo a la página web para que se vea más profesional

A programadores como nosotros a menudo nos intimida el diseño, pero un pequeño esfuerzo puede hacer que tu página web se vea más atractiva y profesional. La captura de pantalla de abajo te dará una idea básica de lo que vamos a hacer.

Múltiples lecturas de DS18B20 en el servidor web ESP32 - Con CSS

Bastante increíble, ¿verdad? Sin más preámbulos, apliquemos algo de estilo a nuestra página HTML anterior. Para empezar, copia y pega el código de abajo para reemplazar la función SendHTML() del sketch anterior.

String SendHTML(float tempSensor1,float tempSensor2,float tempSensor3){
  String ptr = "<!DOCTYPE html>";
  ptr +="<html>";
  ptr +="<head>";
  ptr +="<title>ESP8266 Temperature Monitor</title>";
  ptr +="<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
  ptr +="<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600' rel='stylesheet'>";
  ptr +="<style>";
  ptr +="html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #444444;}";
  ptr +="body{margin-top: 50px;} ";
  ptr +="h1 {margin: 50px auto 30px;} ";
  ptr +=".side-by-side{display: table-cell;vertical-align: middle;position: relative;}";
  ptr +=".text{font-weight: 600;font-size: 19px;width: 200px;}";
  ptr +=".temperature{font-weight: 300;font-size: 50px;padding-right: 15px;}";
  ptr +=".living-room .temperature{color: #3B97D3;}";
  ptr +=".bedroom .temperature{color: #F29C1F;}";
  ptr +=".kitchen .temperature{color: #26B99A;}";
  ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -5px;top: 15px;}";
  ptr +=".data{padding: 10px;}";
  ptr +=".container{display: table;margin: 0 auto;}";
  ptr +=".icon{width:82px}";
  ptr +="</style>";
  ptr +="</head>";
  ptr +="<body>";
  ptr +="<h1>ESP8266 Temperature Monitor</h1>";
  ptr +="<div class='container'>";
  ptr +="<div class='data living-room'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 65.178 45.699'height=45.699px id=Layer_1 version=1.1 viewBox='0 0 65.178 45.699'width=65.178px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><polygon fill=#3B97D3 points='8.969,44.261 8.969,16.469 7.469,16.469 7.469,44.261 1.469,44.261 1.469,45.699 14.906,45.699 ";
  ptr +="14.906,44.261 '/><polygon fill=#3B97D3 points='13.438,0 3,0 0,14.938 16.438,14.938 '/><polygon fill=#3B97D3 points='29.927,45.699 26.261,45.699 26.261,41.156 32.927,41.156 '/><polygon fill=#3B97D3 points='58.572,45.699 62.239,45.699 62.239,41.156 55.572,41.156 '/><path d='M61.521,17.344c-2.021,0-3.656,1.637-3.656,3.656v14.199H30.594V21c0-2.02-1.638-3.656-3.656-3.656";
  ptr +="c-2.02,0-3.657,1.636-3.657,3.656v14.938c0,2.021,1.637,3.655,3.656,3.655H61.52c2.02,0,3.655-1.637,3.655-3.655V21";
  ptr +="C65.177,18.98,63.54,17.344,61.521,17.344z'fill=#3B97D3 /><g><path d='M32.052,30.042c0,2.02,1.637,3.656,3.656,3.656h16.688c2.019,0,3.656-1.638,3.656-3.656v-3.844h-24";
  ptr +="L32.052,30.042L32.052,30.042z'fill=#3B97D3 /><path d='M52.396,6.781H35.709c-2.02,0-3.656,1.637-3.656,3.656v14.344h24V10.438";
  ptr +="C56.053,8.418,54.415,6.781,52.396,6.781z'fill=#3B97D3 /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Living Room</div>";
  ptr +="<div class='side-by-side temperature'>";
  ptr +=(int)tempSensor1;
  ptr +="<span class='superscript'>°C</span></div>";
  ptr +="</div>";
  ptr +="<div class='data bedroom'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 43.438 35.75'height=35.75px id=Layer_1 version=1.1 viewBox='0 0 43.438 35.75'width=43.438px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><g><path d='M25.489,14.909H17.95C13.007,14.908,0,15.245,0,20.188v3.688h43.438v-3.688";
  ptr +="C43.438,15.245,30.431,14.909,25.489,14.909z'fill=#F29C1F /><polygon fill=#F29C1F points='0,31.25 0,35.75 2.5,35.75 4.5,31.25 38.938,31.25 40.938,35.75 43.438,35.75 43.438,31.25 ";
  ptr +="43.438,25.375 0,25.375 	'/><path d='M13.584,11.694c-3.332,0-6.033,0.973-6.033,2.175c0,0.134,0.041,0.264,0.105,0.391";
  ptr +="c3.745-0.631,7.974-0.709,10.341-0.709h1.538C19.105,12.501,16.613,11.694,13.584,11.694z'fill=#F29C1F /><path d='M30.009,11.694c-3.03,0-5.522,0.807-5.951,1.856h1.425V13.55c2.389,0,6.674,0.081,10.444,0.728";
  ptr +="c0.069-0.132,0.114-0.268,0.114-0.408C36.041,12.668,33.34,11.694,30.009,11.694z'fill=#F29C1F /><path d='M6.042,14.088c0-2.224,3.376-4.025,7.542-4.025c3.825,0,6.976,1.519,7.468,3.488h1.488";
  ptr +="c0.49-1.97,3.644-3.489,7.469-3.489c4.166,0,7.542,1.801,7.542,4.025c0,0.17-0.029,0.337-0.067,0.502";
  ptr +="c1.08,0.247,2.088,0.549,2.945,0.926V3.481C40.429,1.559,38.871,0,36.948,0H6.49C4.568,0,3.009,1.559,3.009,3.481v12.054";
  ptr +="c0.895-0.398,1.956-0.713,3.095-0.968C6.069,14.41,6.042,14.251,6.042,14.088z'fill=#F29C1F /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Bedroom</div>";
  ptr +="<div class='side-by-side temperature'>";
  ptr +=(int)tempSensor2;
  ptr +="<span class='superscript'>°C</span></div>";
  ptr +="</div>";
  ptr +="<div class='data kitchen'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 48 31.5'height=31.5px id=Layer_1 version=1.1 viewBox='0 0 48 31.5'width=48px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><circle cx=24.916 cy=15.75 fill=#26B99A r=15.75 /><path d='M14.917,15.75c0-5.522,4.478-10,10-10c2.92,0,5.541,1.26,7.369,3.257l1.088-1.031";
  ptr +="c-2.103-2.285-5.106-3.726-8.457-3.726c-6.351,0-11.5,5.149-11.5,11.5c0,3.127,1.252,5.958,3.277,8.031l1.088-1.031";
  ptr +="C16.011,20.945,14.917,18.477,14.917,15.75z'fill=#FFFFFF /><path d='M45.766,2.906c-1.232,0-2.232,1-2.232,2.234v11.203c0,0,2.76,0,3,0v12H48v-12V2.906";
  ptr +="C48,2.906,46.035,2.906,45.766,2.906z'fill=#26B99A /><path d='M6.005,2.917v5.184c0,0.975-0.638,1.792-1.516,2.083V2.917H3.021v7.267c-0.878-0.29-1.516-1.107-1.516-2.083";
  ptr +="V2.917H0v5.458c0,1.802,1.306,3.291,3.021,3.592v16.376H4.49v-16.38c1.695-0.318,2.979-1.8,2.979-3.588V2.917H6.005z'fill=#26B99A /></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Kitchen</div>";
  ptr +="<div class='side-by-side temperature'>";
  ptr +=(int)tempSensor3;
  ptr +="<span class='superscript'>°C</span></div>";
  ptr +="</div>";
  ptr +="</div>";
  ptr +="</body>";
  ptr +="</html>";
  return ptr;
}

Si intentas comparar esta función con la anterior, te darás cuenta de que son similares, salvo por estos cambios.

  • Hemos usado la fuente web Open Sans, encargada por Google, para nuestra página web. Ten en cuenta que no podrás ver la fuente de Google sin una conexión activa a internet en el dispositivo. Las fuentes de Google se cargan sobre la marcha.ptr +="<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600' rel='stylesheet'>";
  • Los iconos que se usan para mostrar las lecturas de temperatura son en realidad un gráfico vectorial escalable (SVG) definido en la etiqueta <svg>. Crear un SVG no requiere ninguna habilidad especial de programación. Puedes usar el Editor SVG de Google para crear los gráficos de tu página. Nosotros hemos usado estos iconos SVG.

Mejora del código: recarga automática de la página

Una de las mejoras que puedes hacer con nuestro código es recargar la página automáticamente para actualizar el valor del sensor.

Con la incorporación de una sola etiqueta meta en tu documento HTML, puedes indicarle al navegador que recargue automáticamente la página en un intervalo determinado.

<meta http-equiv="refresh" content="2" >

Coloca este código en la etiqueta <head> de tu documento; esta etiqueta meta le indicará al navegador que se recargue cada dos segundos. ¡Bastante ingenioso!

Cargar dinámicamente los datos del sensor con AJAX

Recargar una página web no es demasiado práctico si tienes una página pesada. Un método mejor es usar Asynchronous Javascript And Xml (AJAX) para poder solicitar datos del servidor de forma asíncrona (en segundo plano) sin recargar la página.

El objeto XMLHttpRequest de JavaScript se usa habitualmente para ejecutar AJAX en las páginas web. Realiza la solicitud GET silenciosa al servidor y actualiza el elemento de la página. AJAX no es una tecnología nueva ni un lenguaje diferente, sino tecnologías existentes usadas de formas nuevas. Además de esto, AJAX también hace posible:

  • Solicitar datos de un servidor después de que la página se haya cargado
  • Recibir datos de un servidor después de que la página se haya cargado
  • Enviar datos a un servidor en segundo plano

Aquí está el script AJAX que vamos a usar. Coloca este script justo antes de cerrar la etiqueta </head>.

ptr +="<script>\n";
ptr +="setInterval(loadDoc,1000);\n";
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.body.innerHTML =this.responseText}\n";
ptr +="};\n";
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";
ptr +="</script>\n";

El script comienza con la etiqueta <script>. Como el script AJAX no es más que JavaScript, necesitamos escribirlo dentro de la etiqueta <script>. Para que esta función se llame de forma repetida, usaremos la función de JavaScript setInterval(). Toma dos parámetros: una función que se ejecutará y el intervalo de tiempo (en milisegundos) que indica con qué frecuencia ejecutar la función.

ptr +="<script>\n";
ptr +="setInterval(loadDoc,1000);\n";

El corazón de este script es la función loadDoc(). Dentro de esta función se crea un objeto XMLHttpRequest(). Este objeto se usa para solicitar datos a un servidor web.

ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";

La función xhttp.onreadystatechange() se llama cada vez que cambia el readyState. La propiedad readyState contiene el estado del XMLHttpRequest. Tiene uno de los siguientes valores.

  • 0: solicitud no inicializada
  • 1: conexión con el servidor establecida
  • 2: solicitud recibida
  • 3: procesando la solicitud
  • 4: solicitud finalizada y respuesta lista

La propiedad status contiene el estado del objeto XMLHttpRequest. Tiene uno de los siguientes valores.

  • 200: «OK»
  • 403: «Prohibido»
  • 404: «Página no encontrada»

Cuando readyState es 4 y status es 200, la respuesta está lista. Ahora, el contenido de body  (que contiene las lecturas de temperatura) se actualiza.

ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.body.innerHTML =this.responseText}\n";
ptr +="};\n";

La solicitud HTTP se inicia luego mediante las funciones open() y send().

ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";

Similar Posts

Deja un comentario