Añadir un fichero a un repositorio Mercurial respetando su fecha de modificación

Mercurial es un excelente sistema de control de versiones comparable a Git, pero, en mi opinión, mejor por una gran variedad de razones. En febrero de 2013 di una charla en Python Madrid sobre este tema. Fue muy polémica. Ese es un tema para otro día :-).

Cuando se introduce una nueva versión de un fichero en el sistema de control de versiones, la fecha que se almacena es la fecha del commit. Esto no es problema porque, en general, hacemos el commit segundos o minutos después de hacer las modificaciones en el fichero.

El problema surge cuando queremos añadir un fichero antiguo a un sistema de control de versiones respetando la fecha de última modificación del fichero, no la hora del commit. Esto puede ser importante para respetar la historia del proyecto, preservar la integridad legal del mismo, etc.

Mercurial es versátil. A la hora de hacer un commit podemos especificar la fecha y hora que queremos reflejar mediante el parámetro -d o --date. Por ejemplo:

$ hg commit -d "$(date -u -r FICHERO +'%s') 0" -m "TEXTO"

El comando anterior hará un commit reflejando la fecha y hora del fichero especificado.

Migración de una base de datos LMDB a otra plataforma

LMDB es una base de datos ACID ligera y de alto rendimiento, especialmente recomendable para entornos con pocas escrituras y poca concurrencia de escritura. Dado el cambio de licencia de la extraordinaria Berkeley DB a partir de su versión 6.0, estoy usando LMDB cuando no necesito utilizar las sobresalientes características de Berkeley DB. Cuando necesito tirar de las funcionalidades de Berkeley DB, pero el proyecto no puede utilizar la licencia AGPL3, utilizo la última versión con una licencia utilizable en la práctica, la 5.3.

Una buena parte del rendimiento de LMDB proviene de mapear la base de datos directamente en memoria. Una consecuencia de eso y del uso de punteros y estructuras nativas es que la base de datos no es portable. Cambios de arquitectura entre 32 y 64 bits o de endianness hacen que la base de datos resulte ilegible.

Leer más…

Sincronización de sonido cuando la tasa de refresco de vídeo es irregular

Los motivos por los que el audio y el vídeo se pueden desincronizar son múltiples y variados. Hay que estudiar cada caso en particular y aplicar las medidas correctivas apropiadas. Un caso muy simple, descrito en Determinar automáticamente el desfase de audio en un fichero MKV, se da cuando las diferentes pistas están bien, pero no empiezan en el mismo instante. Esto puede ocurrir con facilidad si, por ejemplo, estamos añadiendo la pista de sonido en castellano a una película que solo tenía audio en inglés. Como se describe en ese artículo, el proceso es trivial.

Tenemos un caso más complicado cuando estamos separando las diferentes pistas de un fichero multimedia, las procesamos por separado y luego volvemos a unirlas. Normalmente no tendremos problemas, pero cuando surjan -y surgirán- hay que saber cómo diagnosticarlos y solucionarlos.

En este artículo estudiaremos un ejemplo real.

Leer más…

Medir y registrar temperatura, humedad relativa y presión atmosférica con un ESP8266: el componente LUA

Tras instalar un intérprete de LUA en mi placa NodeMCU, como describo en Instalar un intérprete de Lua en el ESP8266, lo siguiente es encontrarle una utilidad.

Mi primer proyecto es un medidor de temperatura, humedad y presión atmosférica, registrando toda esa información en un servidor de mi propiedad. Existen plataformas IoT de uso gratuito, pero no me siento cómodo entregándoles información detallada sobre mis costumbres en casa; prefiero que mi trabajo y mis datos no contribuyan a enriquecer una empresa privada ajena y, claro, yo dispongo de servidores y conocimientos para hacerme cargo personalmente de esta tarea.

Para las pruebas empleo dos sensores diferentes. La idea futura es instalar uno dentro de casa (de hecho, en cada habitación) y otro en la calle. Conectar los dos sensores al mismo equipo para su evaluación me permite comparar su rendimiento y relación calidad/precio. Los sensores son:

  • DHT22. Sensor de temperatura y humedad barato y sensible. Conseguí mi unidad por 3.54 €.
  • BME280: Sensor de temperatura, humedad y presión atmosférica. Es más pequeño y, supuestamente, mucho más preciso que el DHT22. Compré el mío por 7.54 €.

Algunas fotos del invento:

Leer más…

Instalar un intérprete de Lua en el ESP8266

En ESP8266 y el "internet de las cosas" y Ejemplos de uso de los comandos AT del ESP8266 presento el interesante chip ESP8266, un pequeño pero capaz microprocesador que cuesta menos de 2€ y que incluye capacidad WIFI. El fabricante ha ido soltando información con cuentagotas, en chino (literalmente) y orientada hacia la programación en C, pero algunos valientes han implementado cosas como Forth (1 y 2).

Forth es un lenguaje muy interesante del que guardo buenos recuerdos, pero en este artículo veremos cómo instalar Lua en un ESP8266. En concreto la implementación de Lua de NodeMCU.

esp8266.jpg

Leer más…

Dios no hizo todos los cargadores USB iguales

En un mundo en el que casi todos los dispositivos pequeños se alimentan con un cargador USB y en el que hay cargadores con varios puertos USB que dicen ser capaces de entregar tres amperios, uno esperaría que los cargadores modernos sean más eficientes y más capaces. Nada más lejos de la realidad. La mayoría de los cargadores USB son malos, muy malos. Por muchos amperios que digan entregar.

Normalmente yo sigo usando el cargador que me vino con el iPhone 3G en 2008. En este artículo verás por qué.

Para las pruebas usaré un teléfono con la batería descargada capaz de cargar a un amperio o, equivalentemente, 5V*1A = 5W (5 watios).

Los teléfonos modernos tienen una potencia máxima de entrada (en este caso, 5 watios), pero reducen el amperaje si el voltaje cae por debajo de los 5 voltios. En un mundo ideal el teléfono se movería al punto donde el producto entre el voltaje y la intensidad es máximo, pero esa sofisticación es mucho pedir y, en la práctica, lo que hace un teléfono normal es reducir su amperaje de carga si ve que el cargador es incapaz de mantener el voltaje en niveles aceptables [1].

[1]

Aunque el factor limitante acostumbra a ser el cargador, lo cierto es que el cable USB puede ser un problema. Si el cable es muy largo o de baja calidad, puede introducir pérdidas apreciables. El efecto es fácil de medir simplemente cambiando el cable por uno más corto mientras usamos el mismo cargador.

Para evitar este efecto en las pruebas, usaré siempre el mismo cable USB.

Lo más importante que hay que tener presente es que el estándar USB marca que, aunque el voltaje oficial es 5V, se consideran aceptables voltajes desde 4.40V a 5.25V. Esto tiene importancia para lo que sigue.

Leer más…

Reemplazar un disco de arranque ZFS en Solaris 10

En agosto de 2015 me llamó por teléfono un antiguo cliente para pedirme que le ayudase a reemplazar uno de los discos de arranque ZFS de un viejo Solaris 10 que aún tiene en producción. La tarea no es trivial porque a) hay poca documentación al respecto, b) la versión de Solaris 10 que usa está muy anticuada y tiene problemas con el arranque ZFS muy conocidos y arreglados en versiones posteriores y c) en ese momento yo me encontraba a 600 Km de Madrid y tendría que actuar con "manos remotas".

A la hora de trabajar con Solaris hay que entender algunos conceptos diferentes a otros Sistemas Operativos:

  • Aunque lo que se lleva ahora es un sistema de particionado de disco EFI, si tu instalación Solaris es antigua, tendrás los discos formateados con Slices [1]. La diferencia entre las particiones tradicionales y los Slices Solaris es que en Solaris los Slices residen DENTRO de una partición. Es semejante a utilizar una partición primaria de la BIOS de un PC para crear dentro particiones lógicas. La idea es similar.

    En un disco Solaris tradicional es muy típico tener una única partición primaria en el disco que, interiormente, está subdividida en diez Slices de diferentes tamaños.

    [1]

    En el mundo Solaris, este tipo de formato se llama SMI. Más información, por ejemplo, en SMI and EFI disk label on Solaris.

    Nota

    Las versiones antiguas de Solaris 10 no permiten arrancar desde un disco con formato EFI. De hecho, tampoco se pueden usar discos EFI en un zpool ZFS "raíz". No sé si eso sigue siendo un problema en versiones modernas de Solaris y derivados.

  • El soporte ZFS en el gestor de arranque GRUB en Solaris 10 es mínimo y más si se trata de una versión no actualizada del sistema operativo. Esto hace que, por ejemplo, GRUB no pueda encontrar los discos de arranque si se cambian de posición física, aunque técnicamente a ZFS le de igual porque guarda sus UUID dentro del propio disco y le da lo mismo que se hayan movido.

    Por el mismo motivo (soporte mínimo en GRUB), no podemos usar ZFS en los discos de arranque a menos que el zpool [2] de arranque conste de un único VDEV [3] formado por un solo disco o por discos en espejo.

    Por lo mismo también, si estamos usando discos de arranque ZFS en espejo, hay que instalar GRUB en todos y cada uno de ellos.

    [2]

    En ZFS un zpool es la colección de discos que forman una unidad de almacenaje.

    [3]

    En ZFS, un vdev es cada una de las unidades de disco virtuales que forman un zpool. Cada vdev o disco virtual puede estar formado por un solo disco, por varios discos duros en espejo o por configuraciones de redundancia RAID-Z, RAID-Z2 o RAID-Z3.

  • Diferentes subsistemas Solaris 10 identifican los discos duros de forma diferente e inconsistente. Hay que tener mucho cuidado para no meter la pata y reemplazar el disco duro que no es. Este problema me ha mordido el culo varias veces aunque nunca de forma catastrófica. Mide todo tres veces para cortar una y comprueba varias veces lo que parece evidente.

    Por ejemplo, fíjate más abajo en que ZFS habla del disco c1d0s0, mientras que en format el disco que nos interesa es el c2d0.

    Es muy confuso. Ten mucho cuidado.

  • Se pueden ver otras restricciones en ZFS Root Pool Configuration Requirements. Por ejemplo:

    Disks that are designated for booting in a ZFS root pool must be less than 2 TBs in size on both SPARC based and x86 based systems.

En este caso los discos de arranque ZFS están en un zpool formado por dos discos en espejo.

Los pasos a seguir son los siguientes:

Leer más…

Estaciones meteorológicas de baja calidad, WeeWX y modificaciones en la base de datos "a pelo"

Mi padre tiene una estación meteorológica pce-fws 20. Se trata de una estación bastante completa con un precio muy barato, ya que cuesta unos 112.53 € (gastos de envío e impuestos incluídos). Ese precio, no obstante, se compensa con unas deficiencias de calidad poco evidentes. Por ejemplo, que el panel solar no sea capaz de cargar la batería o, la causa de este artículo, que la comunicación inalámbrica entre la estación meteorológica y su pantalla no esté protegida.

Vuelvo a decirlo: el enlace inalámbrico entre la estación meteorológica y la pantalla de visualización no va protegido de ninguna forma contra errores de comunicación. ¿Qué puede ir mal? [1].

[1] Aunque aquí señalo lo de estación meteorológica barata pero de baja calidad, lo cierto es que estos problemas también afectan a estaciones caras. En general se trata un problema ignorado de forma sistemática por muchos fabricantes, caros y baratos.

Exacto: de vez en cuando, sobre todo cuando la batería de la estación meteorológica está baja, la comunicación se decodifica incorrectamente y se introducen errores en las medidas. Nótese que proteger esa comunicación es trivial añadiendo algo como un simple Código de Redundancia Cíclica (CRC) e ignorando los paquetes de información incorrectos. Los CRC son triviales de generar y verificar.

Mi padre utiliza WeeWX en una Raspberry PI para gestionar la estación meteorológica y enviar información del tiempo local cada cinco o diez minutos a innumerables webs y servicios como APRS (sí, mi padre es radioaficionado). WeeWX dispone de una funcionalidad que permite, básicamente, comprobar que las medidas que nos interesan estén en un rango adecuado (por ejemplo, que la temperatura exterior está por encima del cero absoluto y por debajo de los 6000 grados centígrados) y rechazar las medidas absurdas. Algo que no sería necesario si la comunicación se protegiese adecuadamente. Lamentablemente esta verificación no nos protege de medidas realistas pero incorrectas. Digamos, una velocidad del viento de 120Km/h cuando fuera no sopla ni una brisa.

A veces, como consecuencia de todo esto, se guardan valores realistas pero patentemente incorrectos para un ser humano. En estos casos es necesario, por tanto, modificar la base de datos para eliminar dichos valores incorrectos.

Leer más…

Corregir el "Aspect Ratio" de un fichero Matroska

Estaba el otro día viendo un episodio de una serie y la imagen me aparecía "alargada" verticalmente. MPlayer me mostraba esto:

VIDEO:  [H264]  704x396  0bpp  25.000 fps    0.0 kbps ( 0.0 kbyte/s)
[...]
Movie-Aspect is 1.25:1 - prescaling to correct movie aspect.
VO: [xv] 704x396 => 704x564 Planar YV12

La fuente original indicó un Aspect Ratio de 1.25:1, que es patentemente incorrecto. La imagen se convierte de 704x396 a 704x564 pixels cuando no debería ser así.

Buscando dónde se guarda el Aspect Ratio en un fichero Matroska, compruebo que no se almacena de forma explícita, sino que en el fichero MKV se puede especificar la resolución de salida deseada. Por tanto podemos cambiar la resolución de salida o, simplemente, eliminar esa información incorrecta y dejar que el reproductor utilice la resolución original de la imagen:

$ mkvpropedit VIDEO.mkv --edit track:v1 --delete display-width --delete display-height
The file is being analyzed.
The changes are written to the file.
Done.

Ahora la imagen se ve correctamente y MPlayer me dice:

VIDEO:  [H264]  704x396  0bpp  25.000 fps    0.0 kbps ( 0.0 kbyte/s)
[...]
Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
VO: [xv] 704x396 => 704x396 Planar YV12

Con este cambio, el vídeo tiene el Aspect Ratio correcto de 1.78:1 (es decir, 16:9) y no se cambia la resolución de la imagen de forma artificial.

Problema resuelto.

Ejemplos de uso de los comandos AT del ESP8266

En ESP8266 y el "internet de las cosas" explico qué es el ESP8266. Tradicionalmente estos módulos vienen de serie con un intérprete de comandos AT. Su uso fundamental es servir de adaptador de puerto serie a WIFI para otro microcontrolador diferente.

No se trata de una configuración que yo necesite, así que lo primero que hago cuando me llega un ESP8266 es reprogramarlo. Antes de hacerlo, no obstante, quiero daros una impresión de cómo va la cosa y sus posibilidades.

La documentación del fabricante está en chino (literalmente), pero poco a poco se ha ido publicando información con cuentagotas en webs de terceros:

Leer más…