Personal Productivity Tracker on Raspberry Pi



My productivity tracker is a “magic mirror”, but instead of time, weather and motivational quotes it shows:


If you spent more than 50% of the time on work tasks, there will be a bright green backlight around the mirror. If less than 50% - the backlight will be red, signaling you need to increase productivity! However, you can set the distribution yourself.





First I will explain the essence of the productivity tracker. Then I will give two different lists of tools and components, so that you can make a full or basic (without LED backlight) version of the tracker that does not require the ability to solder. Further I will show how I did the prototype of my project, so that it was easier for you to prototype your own. You will learn how to adapt the code to your needs, and at the end consider the debugging of the device.

I will not give you a ready-made recipe, I just want to show you how to create a tracker and ask you questions, in search of answers to which you can contribute your ideas by developing a project.

Idea




I was going to write this article for several months. But my old friend by the name "Procrastination" did not allow me to. I was constantly putting off writing, filling my time by watching videos from the dark depths of YouTube.

Once I read an article on procrastination and found out about services that could help in solving my problem: Trello Task Manager and RescueTime Time Scheduler. Both fit my needs perfectly, but after a while I stopped visiting their pages and began to ignore the notifications. And then I came to the idea of ​​my project: I want to display data from applications on a mirror hanging on the wall. Then I definitely will not hide from my duties.

The first draft of the project was simple: I will use the RescueTime API to display my productive / distracting activities, and the Trello API to display the task list for the day. But later I added other features, but more on that below.

Tools and components


I used these tools to create my own tracker, your set may be different!

For the frame :


For LED backlight :


Tools :


Code




This chapter consists of three parts, you do not need all of the above components, while only a Raspberry Pi and a monitor are sufficient.

Configure Raspberry Pi


If you haven’t yet configured the Raspberry Pi, do it . For the project, you will need to install an Apache web server and a PHP-LED controller.

Apache Installation Guide: https://www.raspberrypi.org/documentation/remote-access/web-server/apache.md .

PHP-LED Controller Installation Guide: https://github.com/k1sul1/Raspberry-Pi-PHP-LED-controller .

Now from the project repository, download the index.php file to your Raspberry Pi and put it here: /var/www/html/

If you don’t know how to move files using a Linux terminal, read here: https://www.linux.com/learn/how-move-files-using-linux-commands-or-file-managers .

Code adaptation


This will require a little knowledge of HTML / CSS.

We will adapt the index.php file, which is the heart of the project. Connect the monitor to the Raspberry Pi. If you try to open index.php, it will not work, because you must first insert the API keys into the code. To do this, log into the account on the RescueTime website, go to the developer section and click Activate This Key. Save this key somewhere.

Do the same for the Trello API: sign in to your account and generate an API key on the developer portal.

Now open the index.php file in /var/www/html/ in your text editor and replace [API_KEY] with the keys from RescueTime and Trello. [list_number] - the number of the list that is needed to get the list of tasks from Trello. To generate a number, first create a fresh list in Trello and name it “To-Do”, the tasks from this list will be displayed on the magic mirror.

Now copy from the browser line an address that looks like this:

https://trello.com/b/3hS6yyLo/board-name

add at the end .json: https://trello.com/b/3hS6yyLo/board-name.json
press Enter and the screen will fill with a code. Find the name of your To-Do list in this chaos. It should look like this: {"name":"To Do","id":"5981c123cd1b23f13907cd18"} , here id is your list identifier. Insert its value in [list_number] in the index.php file.

Now open the browser, type localhost in the address bar and press Enter. The graphs should display your data.

Note : the location of the graphs may differ due to the resolution of your monitor. You can adjust the width, height and position of elements in the CSS section of the code.

Now it remains to make a frame for the monitor and connect the LEDs.

Note : If you are not interested in a detailed review of the API, you can skip to the next chapter.

API in detail


The project is based on two APIs:


Although the documentation has all the necessary information, I will explain what data from the API our project uses.

In the time management section, the RescueTime API is called and information about the current time distribution is requested:

"https://www.rescuetime.com/anapi/data?key=[API_KEY]&perspective=rank&interval=hour&restrict_begin=".date('Ym-d')."&restrict_end=".date('Ym-d')."&format=json"

Here
date ('Ym-d') - the current date.
perspective = rank - sort of data sorting. In this case, by "category", that is, what is spent the most time.

After making the call, we receive the file in JSON format (see the data.json file code at the end of the chapter). From it we will take "Time Spent (seconds)" and "Productivity" (can have values ​​from -2 (distracted) to 2, (productive)). Based on this data, you can generate a productivity index with a value greater than 100.

The following call to the RescueTime API:

"https://www.rescuetime.com/anapi/daily_summary_feed?key=[API_KEY]"

You will receive a weekly report (see the file code summary.json at the end of the chapter). This data is used to build the weekly chart.

Calling the Trello API:

"https://api.trello.com/1/lists/[list_number]/cards?fields=name&key=[API_KEY]&token=[Token]"

You will receive data from task cards in Trello:

[{"id":"5a4160103bfcd14994852f59","name":"ceylan cinemagraph"},{"id":"59e8241f6aa8662a51eb7de6","name":"Learn GitHuB"},{"id":"5981c19577c732f826ad8025","name":"Publish Instructible"},{"id":"5a341dba7f17d235d7c5bbd1","name":"SPACE PROGRAM"}]

In the cards you can place the text and transfer it somewhere else.

data.json

Code
 Formatted JSON Data { "notes":"data is an array of arrays (rows), column names for rows in row_headers", "row_headers":[ "Rank", "Time Spent (seconds)", "Number of People", "Activity", "Category", "Productivity" ], "rows":[ [ 1, 1536, 1, "en.0wikipedia.org", "Uncategorized", 0 ], [ 2, 1505, 1, "youtube.com", "Video", -2 ], [ 3, 1178, 1, "OpenOffice", "Writing", 2 ], [ 4, 709, 1, "moodle.bilkent.edu.tr", "General Reference \u0026 Learning", 2 ], [ 5, 602, 1, "google.com.tr", "Search", 2 ], [ 6, 439, 1, "reddit.com", "General News \u0026 Opinion", -2 ], [ 7, 437, 1, "tr.sharelatex.com", "Writing", 2 ], [ 8, 361, 1, "yemeksepeti.com", "General Shopping", -2 ], [ 9, 356, 1, "Gmail", "Email", 0 ], [ 10, 328, 1, "Google Chrome", "Browsers", 0 ], [ 11, 207, 1, "stars.bilkent.edu.tr", "General Reference \u0026 Learning", 2 ], [ 12, 179, 1, "whatsapp", "Instant Message", -1 ], 

summary.json

Code
 [ { "id":1515657600, "date":"2018-01-11", "productivity_pulse":54, "very_productive_percentage":34.2, "productive_percentage":10.6, "neutral_percentage":25.6, "distracting_percentage":0.0, "very_distracting_percentage":29.6, "all_productive_percentage":44.8, "all_distracting_percentage":29.6, "uncategorized_percentage":16.1, "business_percentage":6.0, "communication_and_scheduling_percentage":4.3, "social_networking_percentage":0.0, "design_and_composition_percentage":0.0, "entertainment_percentage":15.2, "news_percentage":3.3, "software_development_percentage":5.4, "reference_and_learning_percentage":22.8, "shopping_percentage":12.9, "utilities_percentage":14.1, "total_hours":2.51, "very_productive_hours":0.86, "productive_hours":0.27, "neutral_hours":0.64, "distracting_hours":0.0, "very_distracting_hours":0.74, "all_productive_hours":1.12, "all_distracting_hours":0.74, "uncategorized_hours":0.4, "business_hours":0.15, "communication_and_scheduling_hours":0.11, "social_networking_hours":0.0, "design_and_composition_hours":0.0, "entertainment_hours":0.38, "news_hours":0.08, "software_development_hours":0.13, "reference_and_learning_hours":0.57, "shopping_hours":0.32, "utilities_hours":0.35, "total_duration_formatted":"2h 30m", "very_productive_duration_formatted":"51m 26s", "productive_duration_formatted":"15m 56s", "neutral_duration_formatted":"38m 34s", "distracting_duration_formatted":"no time", "very_distracting_duration_formatted":"44m 30s", "all_productive_duration_formatted":"1h 7m", "all_distracting_duration_formatted":"44m 30s", "uncategorized_duration_formatted":"24m 11s", "business_duration_formatted":"9m 6s", "communication_and_scheduling_duration_formatted":"6m 26s", "social_networking_duration_formatted":"no time", "design_and_composition_duration_formatted":"no time", "entertainment_duration_formatted":"22m 49s", "news_duration_formatted":"4m 55s", "software_development_duration_formatted":"8m 3s", "reference_and_learning_duration_formatted":"34m 17s", "shopping_duration_formatted":"19m 22s", "utilities_duration_formatted":"21m 17s" }, { "id":1515571200, "date":"2018-01-10", "productivity_pulse":33, "very_productive_percentage":21.9, "productive_percentage":2.3, "neutral_percentage":14.4, "distracting_percentage":11.0, "very_distracting_percentage":50.3, "all_productive_percentage":24.2, "all_distracting_percentage":61.4, "uncategorized_percentage":0.3, "business_percentage":0.0, "communication_and_scheduling_percentage":13.5, "social_networking_percentage":0.0, "design_and_composition_percentage":6.3, "entertainment_percentage":44.7, "news_percentage":4.2, "software_development_percentage":0.0, "reference_and_learning_percentage":15.5, "shopping_percentage":0.0, "utilities_percentage":15.4, "total_hours":2.24, "very_productive_hours":0.49, "productive_hours":0.05, "neutral_hours":0.32, "distracting_hours":0.25, "very_distracting_hours":1.13, "all_productive_hours":0.54, "all_distracting_hours":1.37, "uncategorized_hours":0.01, "business_hours":0.0, "communication_and_scheduling_hours":0.3, "social_networking_hours":0.0, "design_and_composition_hours":0.14, "entertainment_hours":1.0, "news_hours":0.09, "software_development_hours":0.0, "reference_and_learning_hours":0.35, "shopping_hours":0.0, "utilities_hours":0.34, "total_duration_formatted":"2h 14m", "very_productive_duration_formatted":"29m 22s", "productive_duration_formatted":"3m 8s", "neutral_duration_formatted":"19m 18s", "distracting_duration_formatted":"14m 48s", "very_distracting_duration_formatted":"1h 7m", "all_productive_duration_formatted":"32m 30s", "all_distracting_duration_formatted":"1h 22m", "uncategorized_duration_formatted":"27s", "business_duration_formatted":"1s", "communication_and_scheduling_duration_formatted":"18m 5s", "social_networking_duration_formatted":"no time", "design_and_composition_duration_formatted":"8m 30s", "entertainment_duration_formatted":"59m 54s", "news_duration_formatted":"5m 39s", "software_development_duration_formatted":"no time", "reference_and_learning_duration_formatted":"20m 51s", "shopping_duration_formatted":"no time", "utilities_duration_formatted":"20m 39s" }, { "id":1515484800, "date":"2018-01-09", "productivity_pulse":68, "very_productive_percentage":60.4, "productive_percentage":0.5, "neutral_percentage":11.0, "distracting_percentage":7.1, "very_distracting_percentage":21.0, "all_productive_percentage":60.9, "all_distracting_percentage":28.1, "uncategorized_percentage":9.1, "business_percentage":21.9, "communication_and_scheduling_percentage":7.2, "social_networking_percentage":5.1, "design_and_composition_percentage":1.2, "entertainment_percentage":1.6, "news_percentage":12.5, "software_development_percentage":9.1, "reference_and_learning_percentage":28.2, "shopping_percentage":2.9, "utilities_percentage":1.2, "total_hours":2.78, "very_productive_hours":1.68, "productive_hours":0.01, "neutral_hours":0.31, "distracting_hours":0.2, "very_distracting_hours":0.58, "all_productive_hours":1.69, "all_distracting_hours":0.78, "uncategorized_hours":0.25, "business_hours":0.61, "communication_and_scheduling_hours":0.2, "social_networking_hours":0.14, "design_and_composition_hours":0.03, "entertainment_hours":0.04, "news_hours":0.35, "software_development_hours":0.25, "reference_and_learning_hours":0.78, "shopping_hours":0.08, "utilities_hours":0.03, "total_duration_formatted":"2h 46m", "very_productive_duration_formatted":"1h 40m", "productive_duration_formatted":"47s", "neutral_duration_formatted":"18m 23s", "distracting_duration_formatted":"11m 49s", "very_distracting_duration_formatted":"34m 57s", "all_productive_duration_formatted":"1h 41m", "all_distracting_duration_formatted":"46m 46s", "uncategorized_duration_formatted":"15m 7s", "business_duration_formatted":"36m 26s", "communication_and_scheduling_duration_formatted":"11m 59s", "social_networking_duration_formatted":"8m 28s", "design_and_composition_duration_formatted":"2m 4s", "entertainment_duration_formatted":"2m 39s", "news_duration_formatted":"20m 49s", "software_development_duration_formatted":"15m 5s", "reference_and_learning_duration_formatted":"46m 59s", "shopping_duration_formatted":"4m 51s", "utilities_duration_formatted":"2m 3s" } ] 

Prototyping


image





The data is now displayed on the monitor, it's time to design a frame and a mirror. It all depends on your preferences. I took light wood, because it is more suited to my interior.

If you want to choose a different frame design, then there are some great guides:

https://www.instructables.com/id/Smart-Mirror-by-Raspberry-Pi/
https://www.instructables.com/id/Raspberry-Pi-Smart-Mirror/
https://www.instructables.com/id/Magic-Mirror/

The dimensions of the blanks for my frame:

Front side:


Backside:


Assembling the frame and mirrors


image





Some notes:


Electronics assembly


















If you make a basic version without LEDs, you can skip the appropriate step.

LED assembly and installation schemes are taken from two different manuals :

How to control a RGB LED Strip with a Raspberry Pi
Raspberry Pi PHP LED controller

Important notes :

I used such pins:


If you want to use other pins, you will have to change their numbers at the beginning of index.php.

Check




Everything should work fine, but you need a mouse and keyboard to start the browser and enter localhost.

1. Start the terminal and enter: sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart
2. Then enter: chromium-browser --kiosk --incognito "http://localhost/index.php"

Now you can disable the mouse and keyboard. The browser should start and open the index.php file.

Trouble-shooting


I have an API error
Our APIs have restrictions on the number of hits. If you pull them too often, you get an error. To solve this problem, add an update delay to index.php, the default is 360 seconds.

#Seconds to refresh the webpage<br>$sec = "360";

The browser does not open when loading
In different OS the autostart file is in different places. I used Raspbian GNU / Linux 8.0 Jessie, so check where this file resides in your OS.

LEDs shine a different color
Connecting LED strips may vary, and for sure the color connections are mixed. You can fix this by soldering the wires to the correct contacts. You can also adjust the highlight colors using HEX values ​​in index.php.

if ($oran<50) { $led->setHex("#FF0000"); }else { $led->setHex("#00FF00"); }

Here is a HEX calculator to help you.

I want to use other graphics
I used the chart.js js library. If you want to use other graphics, read the documentation: http://www.chartjs.org/samples/latest/

What's next


There are many ways to improve this project. For example:

Source: https://habr.com/ru/post/411797/


All Articles