paint-brush
Construyendo un Arduino Time Tracker Cube con la API abierta de Togglpor@chingiz
10,325 lecturas
10,325 lecturas

Construyendo un Arduino Time Tracker Cube con la API abierta de Toggl

por Chingiz Nazar2021/10/28
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Cómo crear su propio rastreador de tiempo a partir de papel cartón y las API abiertas de Toggl

People Mentioned

Mention Thumbnail

Company Mentioned

Mention Thumbnail
featured image - Construyendo un Arduino Time Tracker Cube con la API abierta de Toggl
Chingiz Nazar HackerNoon profile picture


Pasan las horas, los días, las semanas y los meses, pero siempre sentirás que no hay suficiente tiempo en el día. Parece que de la mañana a la noche trabajas duro, pero no ves el resultado. Para comenzar a usar el tiempo de la manera más eficiente posible, primero debe comprender en qué se está gastando el tiempo. Como sabemos, lo que se mide se gestiona. Además, se requiere mantener un equilibrio entre la vida laboral y personal para no agotarse en el trabajo. Después de ver informes sobre el tiempo dedicado durante una semana o un mes, puede sacar conclusiones y optimizar su rutina diaria o comprender qué actividades brindan excelentes resultados y concentrarse en ellas.


Pasemos a cómo traté de simplificar esta actividad. El seguimiento del tiempo con solo voltear el cubo es una idea muy atractiva. Todos los proyectos de seguimiento del tiempo en casa que he visto cargan datos en archivos CSV o Excel. La singularidad de este proyecto es que el cubo está integrado con un sistema de seguimiento de tiempo que ya funciona con sus propias versiones web, de escritorio y móvil, por lo que podemos realizar fácilmente cambios en los registros, iniciar otra entrada de tiempo desde un teléfono o generar informes para periodos de tiempo especificados. A continuación, encontrará instrucciones detalladas sobre cómo ensamblar un cubo temporizador basado en un microcontrolador.


Todo lo que necesitamos es un sensor acelerómetro (MPU6050) y un módulo wi-fi. Estoy usando NodeMCU pero la misma lógica debería funcionar para Arduino-ESP8266. Aquí hay un enlace a la página de git del proyecto donde puede encontrar el código para este proyecto. También veremos el código con más detalle a continuación.

Hacer que el lado del cubo funcione con el acelerómetro MPU6050

Conexión

MPU6050 tiene una interfaz I2C que debe usarse para la conexión. Para Arduino UNO: A5 — SCL, A4 — SDA, 5V — VCC y GND — GND; para NodeMCU: D1— SCL, D2 — SDA, 3.3V— VCC y GND — GND; He usado NodeMCU en mi caso, pero el código no está limitado dentro de la placa.

Cubo

Puedes usar cualquier cubo pero para facilitar el proyecto he impreso el cubo de papel en cartulina:

plantilla de cubo de papel Cuando esté plegado, coloque el sensor en él y numere los lados:


Los lados numerados son útiles durante algunas configuraciones

Obtener datos sin procesar del sensor

Aquí está el código que nos dará datos de acelerómetro y giroscopio. Cargue el código, abra el monitor serie y establezca la velocidad de transmisión en 9600.


 #include "Wire.h" #include "I2Cdev.h" #include "MPU6050.h" MPU6050 mpu; int16_t ax, ay, az; int16_t gx, gy, gz; void setup() { Wire.begin(); Serial.begin(9600); mpu.initialize(); //connection status Serial.println(mpu.testConnection() ? "MPU6050 OK" : "MPU6050 FAIL"); delay(1000); } void loop() { mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); Serial.print(ax); Serial.print('\t'); Serial.print(ay); Serial.print('\t'); Serial.print(az); Serial.print('\t'); Serial.print(gx); Serial.print('\t'); Serial.print(gy); Serial.print('\t'); Serial.println(gz); delay(50); }


Devolverá valores en el rango entre -32768 … 32767. Para facilitar el trabajo con los datos, hagamos el rango más corto (-100 … 100) dividiendo los valores por 327. Los datos del acelerómetro (ax, ay, az) serán utilizado en nuestro proyecto. Para obtener el lado del cubo, usaremos la aceleración de la tierra, la gravedad.


 Serial.print(ax/327); Serial.print('\t'); Serial.print(ay/327); Serial.print('\t'); Serial.print(az/327); Serial.print('\t'); Serial.println(""); delay(50);

Identificar el lado del cubo

Si abrimos el Serial Monitor que está ejecutando el último bloque de código, podemos ver que da dos valores. Uno alrededor de 0 y el otro alrededor de 50/-50. Esto será aplicable para cada lado del cubo. ej.: -1 -3 46.


Si reescribimos los valores para cada lado podemos ver algo como esto:


 _|X |Y |Z 0|-1 |-3 |46 1|50 |-5 |-1 2|-2 |-50 |-8 3|-50 |0 |-8 4|2 |50 |0 5|7 |3 |-50


Creé una matriz de lados y debe llenarse con la numeración de los lados del cubo de manera adecuada. Esto se hace para facilitar nuestros pasos posteriores.


 ///////////////+X,-X,+Y,-Y,+Z,-Z int sides[] = { 1, 3, 4, 2, 0, 5};


Para verificar si el cubo está en la posición n. ° 1, debemos obtener si la var del hacha es ~ 50. Esto se puede hacer fácilmente mediante una declaración if:


 if(50-epsilon < ax && ax < 50+epsilon ){//40 < 50 < 60 Serial.print("Position #1"); }


Esto debe hacerse para cada lado. Para que nuestro código sea más legible y organizado, he escrito una función separada para él:


 int cube_side = -1; int16_t epsilon = 10; if(checkSide( 50, ax/327) ){ cube_side=sides[0]; } else if(checkSide(-50, ax/327) ){ cube_side=sides[1]; } else if(checkSide( 50, ay/327) ){ cube_side=sides[2]; } else if(checkSide(-50, ay/327) ){ cube_side=sides[3]; } else if(checkSide( 50, az/327) ){ cube_side=sides[4]; } else if(checkSide(-50, az/327) ){ cube_side=sides[5]; } Serial.print(cube_side); Serial.print('\t'); bool checkSide(int16_t side, int16_t a){ //return true or false if(side-epsilon < a && a < side+epsilon ){//40 < 50 < 60 return true; } return false; };

Comprobar que el cubo está en una posición estable

Ahora, podemos obtener el lado del cubo, pero esto no es suficiente para iniciar el seguimiento del tiempo. Necesitamos verificar si el cubo está en una posición estable / no se mueve. Para llegar a él, he creado una matriz que almacenará las últimas 60 medidas y comprobaremos si todas son iguales. Agregaremos un retraso de 50 milisegundos entre cada medición. El seguimiento del tiempo se iniciará después de 3 segundos en una posición estable.


 //Initialization of the array int last_60_measurements[60] = {}; //Moving each measurement to one cell right for (int i=0;i<59;i++){ last_60_measurements[i]=last_60_measurements[i+1];//0=1,1=2.. } //And assign first one with new value last_60_measurements[59] = cube_side; if(checkIfCubeStable(last_60_measurements)){ Serial.print("Stable position"); Serial.print('\t'); } //Checking if all 60 values are same bool checkIfCubeStable(int measurements[]){ for (int i=0;i<60;i++){ if(i==59){return true;}; if(measurements[i] != measurements[i+1]){return false;}; }}


Además, debemos verificar si los datos secundarios ya enviados no son iguales a la posición actual:


 //Initialization of the sent side int sent_cube_side = -1; //Checking if last sent side and current side is not equal if(sent_cube_side!=cube_side){ Serial.print("SEND DATA!"); Serial.print('\t'); //Update the sent side to new side sent_cube_side = cube_side; }


Y finalmente, llegamos al lugar donde necesitamos comenzar a rastrear el tiempo.

¿Qué es Toggl Track?

Si está interesado en el seguimiento del tiempo, ya debería haber oído hablar de la pista Toggl . Para otros, esta es una aplicación de seguimiento de tiempo increíblemente simple con aplicaciones para iOS, Android, macOS, Windows, Linux y versiones web. Pero lo más importante para nosotros es que tiene documentación API abierta .


Para que nuestras entradas de tiempo estén más organizadas aquí, utilizaremos la función de proyectos.

Alternar API de seguimiento

Para trabajar con la API de seguimiento de Toggl, lo único que necesita saber es su correo electrónico y contraseña. El resto de datos necesarios se desvelarán a continuación. Aquí hay algunos comandos para obtener información sobre su espacio de trabajo, proyectos y para probar si las solicitudes de entrada de tiempo de inicio funcionan correctamente.


Para hacerlo, se podría usar una línea de comando con curl. Para macOS y Windows 10 (versión 1803 o posterior), curl está instalado de forma predeterminada, otros pueden encontrar un manual de instalación y hacerlo o simplemente usar una de las herramientas en línea para ejecutar comandos curl, por ejemplo: https://reqbin.com/ rizo Ciertamente, estos comandos se pueden ejecutar en Postman haciendo clic en 'Importar un archivo existente' > 'Texto sin procesar'. Primer comando (reemplace el correo electrónico y la contraseña en consecuencia):


 curl -v -u email:password -X GET https://api.track.toggl.com/api/v8/me


Ejemplo de respuesta:


 { "since":1361780172, "data": { "id":123, "api_token":"1971800d4d82861d8f2c1651fea4d212", "default_wid":777, "email":"[email protected]", "fullname":"John Doe", "jquery_timeofday_format":"h:i A", "jquery_date_format":"m/d/Y", "timeofday_format":"h:mm A", "date_format":"MM/DD/YYYY", "store_start_and_stop_time":true, "beginning_of_week":1, "language":"en_US", "duration_format": "improved", "image_url":"https://www.toggl.com/images/profile.png", "at": "2015-02-17T16:58:53+00:00", "created_at": "2014-07-31T07:51:17+00:00", "timezone": "Europe/London", "retention": 9, "new_blog_post":{}, "projects": [ { "id":90123, "wid":777, "name":"Our best project", "billable":true, "active":true, "at":"2013-02-12T09:47:57+00:00", "color":"5" } ], "tags": [ { "id":238526, "wid":777, "name":"billed" } ], "tasks": [], "workspaces": [ { "id":777, "name":"John's WS", "at":"2012-11-28T11:56:49+00:00", "default_hourly_rate": 0, "default_currency": "USD", "projects_billable_by_default": true, "rounding": 1, "rounding_minutes": 0, "api_token": "ea897..." } ], "clients": [] }


La información importante aquí para nosotros es default_wid o workspaces.id , que se utilizará en nuestra próxima solicitud para obtener información sobre sus proyectos. Reemplace WORKSPACE_ID con el suyo:


 curl -v -u email:password -X GET https://api.track.toggl.com/api/v8/workspaces/WORKSPACE_ID/projects


En la respuesta, encontrarás el id de cada proyecto. (También puede iniciar la entrada de tiempo sin ningún proyecto). Por último, la identificación del proyecto podría usarse en la consulta para iniciar la entrada de tiempo, la descripción podría actualizarse en consecuencia:


 curl -v -u email:password \ -H "Content-Type: application/json" \ -d '{"time_entry":{"description":"Description goes here","tags":[],"pid":PROJECT_ID,"created_with":"curl"}}' \ -X POST https://api.track.toggl.com/api/v8/time_entries/start


Aquí está el ejemplo de código que se ejecutará en Arduino para iniciar la entrada de tiempo:


 POST /api/v8/time_entries/start HTTP/1.1 Host: api.track.toggl.com Content-Type: application/json Authorization: Basic Y2WG...lGsA== Content-Length: 102 {"time_entry":{"description":"Description goes here","tags":[],"pid":PROJECT_ID,"created_with":"curl"}}


El código de autorización se puede encontrar en cualquier respuesta a nuestros comandos o en cartero, abra el 'fragmento de código' > HTTP y vea el mismo código anterior.

Ejecución del comando Arduino HTTPS

Aquí está la lista de bibliotecas que necesitamos:

 #include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <ESP8266WebServer.h> #include <ESP8266HTTPClient.h>


Tendremos que conectarnos a wi-fi. Establecer nombre de red y contraseña:


 const char *ssid = "wifi_name"; //Wifi Network Name const char *password = "wifi_key"; //Wifi Network Key


Establezcamos una credencial de autorización como variable separada:


 const char *authorization = "Basic Y2WG...lGsA==";


Necesitamos establecer rastreadores para cada lado del cubo. El primer elemento es la longitud del contenido, el segundo es la descripción y el tercero es el pid (id del proyecto):


 const char *trackers[6][3] = {{"97", "Email check", "172635855"}, {"93", "Meeting", "172635927"}, {"93", "Reading", "172718034"}, {"109", "Online training courses", "172718034"}, {"84", "Relax", "\"\"" }};


Algunas otras variables que deben declararse para uso futuro:


 const char *host = "api.track.toggl.com"; const int httpsPort = 443; String datarx; //Received data as string int httpsClientTimeout = 5000; //in millis


Inicialización de la conexión wi-fi (en configuración):


 WiFi.mode(WIFI_OFF); delay(1000); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Connecting to wifi: "); Serial.print(ssid); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("Connected to wifi: "); Serial.println(ssid);


A continuación se muestra la función que se utilizará para iniciar el seguimiento del tiempo. Al principio, estamos tratando de establecer una conexión con el servidor. Luego, enviamos una solicitud POST. Después de eso, obtenemos la respuesta y la imprimimos.


 void callhttps_start_time_entry(const char* content_length, const char* description, const char* pid){ WiFiClientSecure httpsClient; httpsClient.setInsecure(); httpsClient.setTimeout(httpsClientTimeout); delay(1000); int retry = 0; while ((!httpsClient.connect(host, httpsPort)) && (retry < 15)) { delay(100); Serial.print("."); retry++; } if (retry == 15) {Serial.println("Connection failed");} else {Serial.println("Connected to Server");} Serial.println("Request_start{"); String req = String("POST /api/v8/time_entries/start HTTP/1.1\") + "Host: api.track.toggl.com\" +"Content-Type: application/json\" +"Authorization: " + authorization + "\" +"Content-Length: " + content_length + "\" +"{\"time_entry\":{\"description\":\"" + description + "\",\"tags\":[],\"pid\":" + pid + ",\"created_with\":\"time_cube\"}}" + "\r\n\r\n"; Serial.println(req); httpsClient.print(req); Serial.println("}Request_end"); Serial.println("line{"); while (httpsClient.connected()) { String line = httpsClient.readStringUntil('); Serial.print(line); if (line == "\r") { break; } } Serial.println("}line"); Serial.println("datarx_start{"); while (httpsClient.available()) { datarx += httpsClient.readStringUntil('); } Serial.println(datarx); Serial.println("}datarx_end"); datarx = ""; }


Ahora podemos llamar a la función para iniciar el seguimiento del tiempo. Los parámetros son la longitud del contenido, la descripción y la identificación del proyecto de la entrada de tiempo que se configuró antes en la matriz de rastreadores.


 callhttps_start_time_entry( trackers[sent_cube_side][0], trackers[sent_cube_side][1], trackers[sent_cube_side][2]);

Conclusión

Al final, me gustaría compartir con ustedes los cambios que ha traído a mi vida el seguimiento del tiempo.


Desde que comencé a controlar mi tiempo, me he vuelto más cuidadoso con mi tiempo. Lo gasto sabiamente y mantengo un equilibrio saludable entre el trabajo y la vida. Para muchos, la idea del seguimiento del tiempo no es atractiva debido al hecho de que el seguimiento del tiempo también es un trabajo. Muchos dicen que con el tiempo se automatiza y requerirá mucho menos esfuerzo que al principio. Pero en mi caso, no funcionó y decidí hacer más fácil este proceso. El cubo de seguimiento de tiempo me ayudó a realizar un seguimiento de mi tiempo de manera simple y fácil.


Además, es fácil editar o ver el informe en la pista Toggl. Fue realmente interesante, pero lo más importante es que este es realmente un proyecto de trabajo para el uso diario. Después de terminar el proyecto, no estaba seguro de si valía la pena escribir y publicar este artículo, pero vi que pasé más de 50 horas de mi tiempo libre en este proyecto de casa y decidí que este trabajo sería útil para alguien al menos para ahorrar. esta vez. Esta es una de las ventajas de controlar su tiempo. Empiezas a apreciar tu trabajo y tu tiempo.


Gracias por su tiempo y espero que dedique su tiempo solo a lo que es importante para usted. Planeo implementar nuevas funciones en el futuro que facilitarán aún más el proceso de seguimiento del tiempo.


Así que mantente atento.