Serie: Tracking de productividad – Parte 4: Captura y almacenamiento de los datos

En capítulos anteriores de esta serie definí los indicadores clave y los eventos que serán capturados en este experimento. A su vez, armé el dispositivo que permite la captura de los eventos producidos por el usuario, los cuales, como mencioné anteriormente, son transmitidos a través del puerto serial del microcontrolador.

En este apartado, como el título lo indica, hablaré acerca del proceso de captura y almacenamiento de los datos.

Qué datos se capturan

El tipo de dato que el dispositivo transmite es únicamente un número, del uno al cuatro, el cual se corresponde con cada uno de los eventos definidos previamente:

  • 1: Inicio de bloque de trabajo.
  • 2: Inicio de bloque de concentración.
  • 3: Fin de bloque de concentración.
  • 4: Fin de bloque de trabajo.

Durante la captura, se agrega la fecha y la hora al número del evento. Estas tres dimensiones serán suficientes para, posteriormente, en la fase de análisis, calcular métricas como:

  • Tiempo total de la jornada laboral por día.
  • Número de bloques de trabajo por día.
  • Tiempo total de concentración por día.
  • Número de bloques de concentración por día.
  • Duración promedio de bloques de concentración por día.
  • Tiempo total no productivo por día.
  • Porcentaje de concentración por día
  • Porcentaje de tiempo no productivo por día.

Adicionalmente, se pueden derivar nuevas dimensiones a partir de la fecha, como el día de la semana o el mes, o incluso cruzarlas con variables externas como la temperatura. Esto permitirá analizar de qué manera distintos factores influyen en mi productividad.

Estrategia de muestreo

Para el muestreo, como se ha establecido previamente, es necesario capturar los eventos de manera manual durante la jornada laboral. El dispositivo cuenta con indicadores visuales (LEDs) y una alarma sonora, los cuales funcionan como retroalimentación sensorial y ayudan a mantener el enfoque durante el uso.

La duración del muestreo será de tres meses, con el objetivo de contar con una base de datos lo suficientemente amplia como para considerarse significativa. Uno de los principales retos de este tipo de muestreo es la consistencia, ya que una captura irregular puede comprometer la calidad de los datos.

Almacenamiento de la información

Los datos serán leídos mediante un script de Python, ejecutado desde Jupyter Notebook y almacenados en un archivo CSV.

Para la lectura de la información se utiliza la librería serial, para el almacenamiento se utiliza pandas y para la asignación de la fecha y la hora se emplea la librería datetime.

A continuación, presento el código que utilizaré para leer y capturar la información del experimento. Este código deberá ser ejecutado cada día para poder registrar los eventos generados a través del dispositivo.

Nota: Los comentarios, nombres de variables e impresiones en pantalla del código se encuentran en inglés.

Importación de librerías

import serial
import pandas as pd
from datetime import datetime

Comunicación con el dispositivo

En esta parte del código se establece comunicación con el microcontrolador. Es necesario ajustar el puerto de acuerdo con el utilizado por el dispositivo y que no se encuentre abierto por ningún otro programa.

PORT = "COM6"        #adjust port
BAUDRATE = 9600
ser = serial.Serial(PORT, BAUDRATE, timeout=1)
print("Serial port open")

Lectura del archivo CSV

Esta sección del código se encarga de leer el archivo CSV donde se almacenarán los datos, y crearlo en caso de que no exista.

CSV_FILE = "concentration_tracking.csv"
try:
    pd.read_csv(CSV_FILE)
except FileNotFoundError:
    df = pd.DataFrame(columns=["date", "time", "event_id"])
    df.to_csv(CSV_FILE, index=False)
    print("CSV file created")

Definición de la función de captura y registro de los datos

Esta función es el corazón del script. Se encarga de leer los eventos enviados por el microcontrolador, decodificarlos, asignar la fecha y la hora, estructurar la información y guardarla en el archivo CSV.

def read_events(num_events=10):
    events = []

    for _ in range(num_events):
        line = ser.readline().decode("utf-8").strip()

        if line:
            try:
                event_id = int(line)
                now = datetime.now()

                row = {
                    "date": now.strftime("%Y-%m-%d"),
                    "time": now.strftime("%H:%M:%S"),
                    "event_id": event_id
                }

                events.append(row)

                pd.DataFrame([row]).to_csv(
                    CSV_FILE, mode="a", header=False, index=False
                )

                print("Event registered:", row)

            except ValueError:
                print("Invalid entry:", line)

    return pd.DataFrame(events)

Llamado de la función de captura y registro de los datos

La siguiente línea de código ejecuta la función definida anteriormente. El parámetro num_events puede ajustarse para incrementar o reducir el tiempo en el cual la función permanece “escuchando” al microcontrolador. Es importante asegurarse de que esta llamada esté activa; de lo contrario, los eventos no serán registrados.

df_events = read_events(num_events=10)
df_events

Cuando la función termina de ejecutarse, imprime en pantalla los eventos que fueron capturados:

Event registered: {'date': '2026-02-05', 'time': '09:38:24', 'event_id': 1}
Event registered: {'date': '2026-02-05', 'time': '09:38:25', 'event_id': 2}

Calidad y validación de los datos.

El microcontrolador incluye condiciones en su código que evitan que se graben dos eventos idénticos de manera consecutiva. Sin embargo, siempre existe la posibilidad de error humano.

En esos casos, es posible editar el CSV manualmente para eliminar registros capturados accidentalmente o corregir entradas incorrectas. Lo único a tomar en cuenta es que la función de lectura y escritura de datos no debe estar ejecutándose al momento de realizar estas modificaciones. Asimismo, es necesario cerrar el archivo CSV para que el script pueda operar correctamente.

Siguientes pasos

Con la captura y el almacenamiento de los datos resueltos, el siguiente paso del experimento será el análisis de la información generada. En esta etapa buscaré transformar los eventos y timestamps en métricas concretas que me permitan entender cómo se distribuye mi tiempo a lo largo de la jornada laboral y qué tan consistente es mi nivel de concentración.