Acerca de Jose Antonio

Yo soy el que manda aqui... ¿Que pasa?

Construyendo un dispositivo inteligente con nodemcu y un display OLED

Últimamente se están poniendo de moda los dispositivos «inteligentes» que, básicamente, consiste en cacharros que están conectados de una manera o de otra a internet o a nuestra red doméstica y que aceptan comandos desde la red para controlar sus distintas funciones.

La verdad es que han bajado mucho de precio y el poder controlarlas desde los distintos asistentes de voz le dan un extra adicional. He trasteado un poco con Alexa y con Google Home, pero todavía estoy en el proceso de encontrarle el sitio correcto. En cualqueir caso, como soy un alma inquieta he preferido ver cuanto me costaba crear mi propio «dispositivo inteligente» con los materiales que tenía a mano… Esto es lo que he usado:

  • Pantalla OLED de 1,3″ con el chip SSH1106 de 128×64. En concreto esta.
  • Una placa Weimos D1 mini (compatible), que se basa en el chip ESP8266. En concreto esta.
  • Un relé preparado para 5V. En mi caso este.

El chip ESP8266 es una maravilla que integra wifi junto con un microcontrolador que puede ser programado desde el IDE del Arduino (entre otras formas) y el empaquetado en forma de placa nocemcu hace que sea muy sencillo hacer proyectos con este, siendo más barato y más potente que un arduino habitual. De hecho los componentes de este proyecto comprados en aliexpress (quitando cables y gastos de envío) no suman más de 6 Euros… Irresistible para montar un prototipo.

Al lío… Es esquema de conexiones es este:

En realidad el pulsador no hace falta, lo he incluido para poder comunicar al dispositivo manualmente el cambio de estado (es un rollo tener que hacerlo todo en remoto) y no es necesario para la primera versión.

Para poder programar la placa desde el IDE del Arduino vamos a tener que ir a la sección de Archivo->Preferencias y añadir la url http://arduino.esp8266.com/stable/package_esp8266com_index.json en el campo Gestor de URLs Adicionales de Tarjetas, quedando como en la imagen:

Luego nos vamos a Herramientas->Placas->Gestión de tarjetas y buscamos ESP8266 e instalamos la versión de ESP8266 Community.

Con esto ya nos aparecerá el tipo de tarjeta Wemos o NodeMCU en la lista de tarjetas que podemos conectar con el IDE.

Lo siguiente es encontrar una librería que nos permita interactuar por I2C con nuestra pantalla (y que sea lo más flexible posible para usos futuros). Esto es lo que me llevó más tiempo, básicamente porque los ejemplos que proporcionan están preparados para otro chip y la nomenclatura de los pines es diferente… Al final la mejor es esta:

https://github.com/ThingPulse/esp8266-oled-ssd1306

Yo he usado como base el ejemplo que viene al instalar la placa y se llama WIFIServer (creo que lo han cambiado por una versión nueva, os dejo el código completo al final de todas formas). El funcionamiento es de tal manera que al arrancar se conecta a la red wifi que tengamos configurada y queda esperando conexiones, cuando recibe una petición https://server_ip/gpio/0 ponemos a cero el GPIO2 y si recibimos una https://server_ip/gpio/1 lo ponemos a 1… Como esa salida la tenemos conectada al relé, pues ya podemos encender o apagar lo que queramos desde la web.

Para sacar la información por la pantalla, básicamente, utilizo la función drawString que me imprime en las coordenadas dadas de la pantalla una cadena (y en la fuente que hayamos seleccionado antes)… Podéis verlo en funcionamiento en este video:

Os pongo el código antes de integrar lo del botón… Básicamente lo que falta por poner es que cuando detectemos una pulsación del botón (D3 pase a cero) cambiemos el estado del pin conectado al relé (así tenemos control manual, cosa que echo de menos en las bombillas inteligentes, por ejemplo).


#include <ESP8266WiFi.h>
#include "SH1106Wire.h"

const char* ssid = "tussid";
const char* password = "tupassword";

SH1106Wire display(0x3c, 4, 5);

WiFiServer server(80);

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

  pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(0,0,"Connecting...");
  display.display();
      
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  display.clear();
  display.drawString(0,0,String(ssid));
  display.drawString(0,10, "IP: "+WiFi.localIP().toString());
  display.display();
    
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  digitalWrite(2, val);
  display.setColor(BLACK);
  display.fillRect(0, 26, 100, 10);
  display.setColor(WHITE);
  display.drawString(0,26,"GPIO: "+String(val));
  display.display();
  
  client.flush();

  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  client.print(s);
  delay(1);
  Serial.println("Client disonnected");
}

Si habéis leido el código veréis que hay algunas cosas que se hacen de más, por ejemplo, pintamos un rectángulo en negro para borrar la línea antes de pintarla de nuevo con el valor del GPIO. Eso es debido a que esta librería está pensada para borrar la pantalla cada vez que la actualicemos y, por eso, no limpia el hueco en el que va a escribir (igual podemos hacer un fork que lo solucione, ya veremos) y sin esa limpieza las letras se escriben unas encima de otras.

Una nota final… El servidor no envía cabeceras CORS, por lo que si vais a utilizarlo desde javascript en cualquier otro servidor os saltará un error en la consola (y en mac ni siquiera hará la llamada real), en linux y windows funcionará aunque no recibiréis la respuesta.

Sigo modificando el código y demás a ver qué termino consiguiendo… Hasta es posible que le diseñe un PCB… Ya os iré contando.

No me extraña nada que apple se vaya al carajo

No voy a hablar sobre la coyuntura de ventas o innovación de la empresa de los iphone, no, de eso ya se encargan otros que saben mucho más que yo y, además, siempre he creído que apple no merecía ser la empresa con mayor capitalización bursatil del mundo… Pero, la verdad, no me extraña que se termine yendo al carajo.

El caso es que estamos haciendo una aplicación móvil para un cliente, que ya tenemos en beta en la play store y que, por supuesto, queríamos tener en beta también en la app store. Así que, al día siguiente de subir la versión android, generamos la versión ios (después de miles de problemas con certificados y perfiles de desarrollo que nadie entiende) y la subimos a itunesconnect. La ponemos como disponible para betatesting con TestFlight (mucho más limitado que la versión beta de Android, pero es lo que hay) y nos exigen una revisión por su parte.

Esperamos pacientemente y nos encontramos esto (literal, que es un pantallazo):

En resumen, que Apple considera que nuestra app no tiene suficientes funcionalidades y no nos la aprueba ni para beta testing… ¡Ole sus huevos!

Así no me extraña que la gente termine asustada por la dependencia brutal de cualquier desarrollo con la tienda y sus revisores de mierda… Y es que, aunque se mueva más dinero en esa plataforma, el desarrollador está completamente indefenso ante las arbitrariedades de la empresa.

NOTA: al final, tras un proceso de revisión adicional, han accedido a que podamos hacer el beta testing… Eso si, de una versión que ya es vieja con respecto a la de Android.. :-(

Adiós 2018, Hola 2019

Yo no suelo ser de los que hacen resumen del año cuando este termina, para mi el día 1 de enero es solo el día siguiente al 31 de diciembre. Que alguien eligiese esta parte de la rotación terrestre para indicar el comienzo de un nuevo periodo solo es una anédota más de nuestra civilización. En cualquier caso, como todo el mundo sabe, cualquier punto que elijas es bueno para hacer una retrospectiva. Así que, dado que hoy es el último día de este año, creo que es bueno que me pare a ver qué he aprendido del nuevo año y me plantee unos objetivos para el siguiente. Así el año que viene, si sigo teniendo ganas de escribir, puedo usar este post como recordatorio de lo iluso que he sido…

Bye, bye 2018

Este año solo he escrito 14 post en el blog, por poco uno por mes, eso significa que he tenido poco tiempo libre o, al menos, poco tiempo para reflexionar sobre cualquier cosa que no fuese urgente… Lo anoto como deseo para el año nuevo: escribir, al menos, dos post al mes. No es que sea la repanocha, pero eso significará que dedico un ratito más a pensar.

Lo que he aprendido

Este año prometía ser el año en el que la ciberseguridad, por fín, entraría en los pensamientos del público en general, el nuevo RGPD atenazaba de miedo a todos los que tenían una web y se veían ya denunciados y pagando un pastón en multas… Nada de eso ha sucedido y la lección es clara: A nadie le interesa la ciberseguridad. Facebook ha sido denunciada por vender nuestros datos sin nuestro consentimiento, Twitter ha ido regalando nuestras contraseñas, miles de millones de ellas circulan por la red y, seguro, que tu has recibido un correo de extorsión con alguna de tus contraseñas. No obstante, la gente sigue en Facebook, Twitter sigue siendo la barra del odio y la mayor parte de la gente sigue usando la misma contraseña en cientos de sitios. Quizá no lo estamos haciendo lo suficientemente bien para que el público se conciencie de que su seguridad y privacidad en internet es ya más importante que la de su propio domicilio.

He aprendido mucho sobre cómo funciona la justicia. He salido bien de un concurso de acreedores y me han denunciado unos sinverguenzas que tendrán su vista oral el 14 de enero de 2020

He confirmado que hay mucha gente que solo se preocupa por ella misma y por su círculo cercano y otros que son tan maravillosos que se ofrecen sin pedir nada a cambio y que, siempre, ofrecerse da más satisfacciones que verse obligado a algo. Ampliar el círculo de personas a las que te ofreces es mucho mejor que intentar mantener a las demás fuera el mayor tiempo posible. Desgraciadamente este año ha sido uno de los peores en lo que a «borreguismo» se refiere. La gente ha perdido todo su espíritu crítico o, en el mejor de los casos, lo ha sustituido por una lista muy limitada de fuentes a las que seguir. De tal manera que, si estas fuentes no tienen objecciones en lanzar bulos o simplemente, mentir de manera descarada, habrá un rebaño de creyentes detrás haciendo de altavoz y propagando estas mentiras a amigos y conocidos que pueden picar esta vez influenciados por una persona de su confianza.

En el aspecto técnico (esto se estaba poniendo cada vez más profundo) he aprendido a hacer una placa PCB, a utilizar NFC en los teléfonos, a utilizar las librerías de autocompletado de Android, a usar eficientemente los servicios de la nube de Azure, AWS, Google Cloud e incluso IBM (bluemix). He aprendido un montón sobre displays de e-ink, he avanzado en python (cada día me gusta más), he construido mi propia alexa y estoy experimentando con domótica y, por fi, estoy usando git extensivamente. Lo que más tiempo me ha quitado este año ha sido aprender los protocolos seguros de pagos con tarjetas de crédito (no, no voy a extenderme), conocimiento que espero que me sirva mucho tiempo porque lo he adquirido a base de sangre, sudor y lágrimas.

También he descubierto que arreglar ordenadores retro no es tan sencillo pero, aún así, es algo que me sigue fascinando. Mi colección retro ha aumentado con un MSX, un C64 (dos, uno no funciona), un Atari ST y, próximamente, un Amiga 500.

En el aspecto empresarial he aprendido que da igual la calidad del servicio que ofrezcas o la confianza que tengas, nadie te paga cuando corresponde. Que más vale tener fondos propios o una buena línea de crédito y, aún así, tu negocio se puede ir al carajo por un «error administrativo» de tu cliente que, curiosamente, sucede siempre justo antes de tener que pagarte.

En el aspecto personal he descubierto hasta que punto soy capaz de auto-explotarme. Trabajar fines de semanas y fiestas, estar hasta las 5 de la mañana en la oficina sin pensar siquiera que tu cliente no se lo merece y que, total, tampoco te lo va a pagar adecuadamente. Como deseo para el año que viene me pongo el no trabajar en fin de semana para ningún cliente que no me lo pague por adelantado y, en caso de hacer esos trabajos, tomarme días libres a cambio. A nadie le importa el tiempo que dedicas a trabajar… ¡despierta!

También he aprendido que la salud es un tesoro que no valoramos lo suficiente, aunque, a pesar de los ejemplos cercanos de personas que han tenido, o tienen, problemas importantes de salud, no he sido capaz todavía de concienciarme de ello. Si, he intentado ir al gimnasio regularmente, hasta que mi auto-explotación me lo ha impedido, he intentado seguir una alimentación sana hasta que mi frustración me ha llevado a comer compulsivamente de nuevo y he dejado pasar problemas de saludo porque me iban a restar tiempo para otras actividades cuando, en realidad, cualquier inversión en salud lo que va a darte es más tiempo de mejor vida.

Lo que quiero para el 2019

Quiero estar más tiempo con mi familia. Con toda mi familia y sin sentirme obligado a ello y sin hacerlo por compromiso.

Quiero trabajar menos en cosas que solo dan dinero y trabajar más en cosas que mejoren el mundo o que enriquezcan mi vida y la de los demás.

Quiero aprender a decir que no a los clientes, hasta ahora soy demasiado «fácil» de convencer

Quiero recuperar la fe en la especie humana, espero que el sentido común y el espíritu crítico vuelvan a todos antes de que sea tarde.

Quiero poder seguir haciendo lo que me gusta y disponer de tiempo para cuidarme, cuidar de mi familia y servir de mejor ejemplo a mis hijos.

En suma, quiero que el 2019 me permita descubrir a más buenas personas y me permita tolerar mejor a los que no lo son.


Seguro que me dejo un montón de cosas, tanto en lo que he aprendido como en lo que deseo para el 2019, pero si se una cosa… Que os deseo un Feliz y Próspero 2019.

Olvidarse de las contraseñas DEFINITIVAMENTE en Android

Una de las preguntas más redundantes que nos han hecho en los múltiples eventos en los que hemos presentado NoMorePass es ¿Puedo usarlo para hacer login en el propio móvil? Nuestra respuesta, como siempre, era positiva, pero con restricciones, hasta el momento solo podíamos copiar-pegar la contraseña… Y digo hasta ahora porque Android 8 incluyó una novedad que nos venía al pelo: el Autofill Framework.

Este framework permite a algunas aplicaciones registrarse como servicio proveedor de credenciales de forma que, si el usuario selecciona esa aplicación, el sistema permite que la aplicación «recomiende» valores posibles para los campos a rellenar en las aplicaciones… Dicho y hecho, esto es lo que los usuarios de NoMorePass nos estaban pidiendo y esto es lo que hemos conseguido (dentro video:)

Autocompletar con NoMorePass

Como véis es algo sumamente sencillo, seleccionar NoMorePass como proveedor de autocompletar y a partir de ese momento todas las contraseñas estarán disponibles para autorellenado cuando las necesitemos.

La primera vez que usamos una contraseña para una app nos preguntará qué contraseña enviar (y usaremos el mismo método que con las webs) y, lo que es más, si metemos a mano una contraseña se nos preguntará si queremos registrar esa contraseña en NoMorePass y así no tener que volver a meterla nunca más… Así hacemos realidad nuestro lema: Olvida tus contraseñas.

¿Y qué pasa con iOS? bueno, apple nunca nos ha puesto las cosas fáciles, más teniendo en cuenta su empeño con quedarse con las credenciales de todo el mundo en su iCloud. Sin embargo, a partir de iOS 12, Apple ha abierto un poco la mano a esta posibilidad y ofrece Servicios de autenticación que, cómo no, vamos a integrar lo antes que podamos.

Mientras… Si tienes Android 8.0 o superior, puedes disfrutar de esta nueva funcionalidad descargádote la versión 1.11.1 o superior de la app.

Varias versiones php en tu servidor

Esto de las versiones del php me ha traído de cabeza desde que decidieron que algunas versiones iban a ser incompatibles con otras… Tan traumático fue el cambio a php5 que la comunidad ha tardado muchos años en decidirse a utilizar otra versión, tanto que se han saltado un número y ahora vivimos con la versión 7.x. En este caso os dejo la receta para poder cambiar de una versión a otra de php en un servidor ubuntu y así poder probar si algo funciona con la versión más nueva o hay que seguir «pegado a la versión anterior».

Yo me he creado dos archivos para hacerlo: 

switchTo5.6.sh

!/bin/bash
a2dismod php7.2
a2enmod php5.6
update-alternatives --set php /usr/bin/php5.6
update-alternatives --set phar /usr/bin/phar5.6
update-alternatives --set phar.phar /usr/bin/phar.phar5.6 
update-alternatives --set phpize /usr/bin/phpize5.6
update-alternatives --set php-config /usr/bin/php-config5.6
service apache2 restart

switchTo7.2.sh

#!/bin/bash
a2dismod php5.6
a2enmod php7.2
update-alternatives --set php /usr/bin/php7.2
update-alternatives --set phar /usr/bin/phar7.2
update-alternatives --set phar.phar /usr/bin/phar.phar7.2 
update-alternatives --set phpize /usr/bin/phpize7.2
update-alternatives --set php-config /usr/bin/php-config7.2
service apache2 restart

Recordad que para que todo funcione habéis tenido que incluir los repositorios que tengan las distintas versiones de php. En mi caso incluí este:

sudo add-apt-repository ppa:ondrej/php

Y que tenéis que instalar todas las dependencias del proyecto en cuestión. En mi caso fueron estas (es un proyecto LAMP):

sudo apt-get install -y apache2 libapache2-mpm-itksudo apt-get install php php-mysql php-curl php-gd php-intl php-pear php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php7.2-xml  php-mbstring libapache2-mod-php

No es la solución ideal pero permite cambiar a una versión más «segura» en cualquier momento y asegurar que los proyectos siguen funcionando al margen de la versión actual de php.

En cualquier caso, seguro que surgen más problemas con el versionado de las librerías, ahí ya no queda más que rezar y esperar que todo siga funcionando «más o menos» como antes.