Archivo por meses: noviembre 2020

A ritmo de conga (16)

Hace unos días me encontré con un problema raro: mi aspiradora no respondía a mis órdenes en la app. Pero lo mas raro era el estado de los botones: estaba cargando, pero el botón de «volver a casa» estaba activo, y el de «empezar a limpiar» estaba desactivado.

Un vistazo rápido a los logs me permitió descubrir que el estado actual de la aspiradora era «10», y antes había pasado por el «9» y por el «7». Esto era muy raro, pues los únicos estados que conocía hasta ahora iban desde el «1» (limpiando), hasta el «6» (en la base, batería cargada), tal y como comenté en la entrada «A ritmo de conga (6)».

Obviamente esto era muy raro, así que empecé a investigar revisando los logs, y descubrí qué ya me había ocurrido lo mismo en dos ocasiones más. Las preguntas obvias eran: ¿por qué? y ¿Qué significaban esos nuevos estados?

Entonces me fijé en un detalle raro: antes de pasar al modo «9», la aspiradora estaba limpiando (modo «1»), pero la batería estaba muy baja. De pronto se puso en modo «9», y unos segundos después pasó a modo «10», y entonces el nivel de la batería, de pronto, empezó a subir. Y cuando llegó al 100%, volvió a modo «1», o limpiar.

La respuesta era obvia: cuando la aspiradora está limpiando y ve que la batería está demasiado baja como para terminar el trabajo, ella sola se vuelve a la base (modo «9») para cargarla de nuevo (modo «10») y continuar la operación donde la dejó. El «7» todavía no se qué puede ser. A lo mejor tiene que ver con un par de veces que se me quedó atascada por culpa de un reflejo del sol (no se por qué, pero si da el sol en el parqué, el sensor antiescaleras se lía), pero tengo que hacer más pruebas para confirmarlo.

Así, la lista de estados posibles pasa a ser:

  • 1: limpiando
  • 2: detenida
  • 4: regresando a la base
  • 5: en la base, cargando la batería
  • 6: en la base, batería cargada
  • 7: ??????
  • 9: regresando a la base por batería baja
  • 10: en la base, cargando batería, para continuar un trabajo previo interrumpido por batería baja

A ritmo de conga (15)

Hoy hice algunos cambios extra en el repositorio de OpenDoñita. Para empezar, dado que han actualizado OSMC y ya trae Python 3.7, ahora ya es posible instalar mi servidor directamente en una Raspberry Pi con él. Así lo hice, así que aproveché para añadir un nuevo instalador que sea más sencillo. Ahora, al ejecutar install.sh, se bajarán los paquetes necesarios (tanto de python como del sistema operativo), se instalará todo en el sitio correspondiente, y se lanzarán los servicios necesarios.

Por otro lado, he escrito un nuevo programa para emparejar la aspiradora. Tiene esta pinta:

Gracias a ella, ahora es un poco más sencillo realizar el emparejado desde cualquier ordenador, con la única condición de que éste tenga WiFi.

Crust y protothreads

Hace tiempo había descubierto un curioso mecanismo denominado protothreads. Se trata de una manera de añadir capacidades asíncronas a C. El truco es bastante curioso, pues se basa en una característica poco conocida de C, que consiste en que un switch puede saltar a la mitad de un bucle, ya sea for, while o do…while. Esto es, este código es legal:

switch (a) {
default:
    while(1) {
        do something
        return;
case XXXX:
        do more things
    }
}

Esto funciona perfectamente en C, y además es perfectamente legal, gracias a la definición explícita de cómo funcionan los bucles en este lenguaje.

La idea detrás de esto es generar a mayores una serie de macros y definiciones que permitan embellecer el código, y hacer que se parezca más a programación asíncrona.

La cuestión es que llevo unas semanas trabajando en un proyectillo en C que utiliza eventos y programación asíncrona, y para simplificar y mejorar el código decidí implementar protothreads. Por supuesto, también utilizaba mi viejo analizador estático crust para analizar el código y detectar errores, y justo aquí me encontré con el problema: no era capaz de analizar correctamente estas estructuras.

Así que aquí tenía dos opciones: o pasar de crust, o actualizarlo para que lo soporte. Y obviamente me decidí por lo segundo.