Introduction: Productivity Tracker - Powered by Raspberry Pi

Productivity Tracker is a magic mirror, but instead of displaying the time, weather and a motivating quote, it displays 4 things;

  • The percentage of the time you have spent on productive material on your computer and phone for that day.( RescueTime)
  • A radar graph showing how much time you spent along with the categories of the programs-apps you used compared to yesterdays usage.(RescueTime)

And if the percentage of the time you've spent on productive material is over 50% the LEDs will display a bright green color. If it is under 50% it will display a red color, signaling you to be more productive! You can also set a goal yourself.

Outline

In the first step, I will explain the idea behind productivity-tracker. Next, I'll give you two different tools&parts list, so you can build the full project or a basic version(Doesn't include the LEDs) that does not require soldering skills. Later I will show you how I prototyped my version of the project, so you have an idea on how to model your own prototype. Also, I will get into detail at the code section so you can customize the code for your own needs. At the end, I will give you a Trouble-shooting guide based on the problems I encountered during this build. And expand the list with your questions.

The purpose of this instructable is not just to give you a cookbook. I'll show you the way I built this project and provide you with open-ended questions, so you can add your own ideas, and take this project even further. I strongly encourage you to share your build when it's done! Let's get started.

Step 1: The Idea

I have been intending to write this Instructable for months. But an old friend of mine who goes by the name of "Procrastination" didn't let me. Procrastination is the act of delaying or postponing a task or set of tasks, and instead of doing those tasks filling the time with watching videos from the dark depths of YouTube.

One day while reading an article on procrastination I came across multiple apps/programs that would help me with my problem, Trello as a task management app and RescueTime as a time management app. Both worked perfectly for my needs, for a time at least. After a while, I stopped checking the apps altogether and ignored the notifications. That is when I came up with this project. I would display the data from apps on a mirror hanged up on my wall. This way there was no escape from my responsibilities.

The first draft I draw for my project was fairly simple. I would use the RescueTime API to display my Productive/Distractive work percentage. And use the Trello API to display my to-do list for the day. But after a while, I added more features that I will get in detail in the next steps.

Step 2: Tools & Parts

Note: This is a list of tools I used during my build, they do not have to be the same for your build!

For the Base:

  • 4 Meters of 7x15cm playwood - 6$ - It depends on your screen size
  • 30x40cm one sided mirror - depends on your screen size
  • 25x35cm Samsung monitor - 15$ - Found at a flea market. any monitor would do
  • HDMI cable - 2$

For the Led Lightning:

Tools:

  • Wood saw
  • Wood glue
  • Soldering Iron (For the LED lighting)

Step 3: The Code

This step will be in 3 parts, you don"t need all the parts listed in the previous step. A Raspberry Pi and the monitor you"ll use for this project should be enough for the prototyping stage.

Setting up your Raspberry Pi

If you did not set your Raspberry Pi yet go ahead and do it here. For this build, you"ll need to install Apache for the web server and the PHP-LED-controller.

To install Apache follow this official guide.

To install the PHP-LED-controller follow this guide by Christian Nikkanen

Now download the index.php file from the project repository to your Raspberry Pi and put it on this path:

/var/www/html/

If you are unfamiliar with moving files around in Linux Terminal, you can look at this guide to get you started.

Customize the Code

Note:This part requires a little bit of HTML/CSS knowledge if you are using a different monitor.

The customization will be done on the index.php file which is the hearth of this build. Now go ahead and connect your monitor to your Raspberry Pi if you didn't already.

Now if you try to open the index.php file it won't work because you first have to fill the API keys in the code, for that go to the RescueTime website and open an account. Next, go to the developer section and create an API key by pressing Activate This Key. Write Your API key to somewhere.

Do the same for your Trello API key, Open an account and go to the developer portal to generate an API key.

Next, open the index.php file that you put into /var/www/html/ in your favorite text editor, and replace [API_KEY] with your own API key that you got from RescueTime and Trello accordingly. The[list_number] is the list number that you use for your to-do list Trello. To get that number first create a fresh list on Trello and call it "To-Do", this will be the list that you'll use for your to-do list and it will appear on the mirror.

Next, Take the URL on your address bar that looks like:

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

and add .json to it like this:

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

and press enter, next you'll see a code mess on the screen. Try to find your list name ''To-Do" on that mess. It should look something like this: {"name":"To Do","id":"5981c123cd1b23f13907cd18"}, That Id is your list Id. put that number to [list_number] on the index.php file.

Now open your browser and type localhost to the address bar and press enter. You should see your data displayed on the graphs.

Note:The placements of the graphs can be different because of the resolution of the monitor that you are using. You can edit the width, height and location of the elements in the CSS part of the code.

Now all left to do is to design a box around the monitor and connect the LEDs.

Note: If you are not interested in the API's in detail you can skip to the next step. In the API's part I will get in detail how the whole program works and gets data from APIs.

The API's (in detail)

The hearth of this project is the Two APIs;

Although the documentation has detailed information available, I'm going to explain which data from the API this project is using.

On the time management part, the RescueTime API call that gets the time info for the current day is,

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

where,

date('Y-m-d')is the current date

perspective=rankis the data sorting type in this case "rank" which stands for most time spent

This call will give a file in JSON format that looks like this:(look at data.json at the end of this step)

The data we use from this file is the "Time Spent (seconds)" and the "Productivity" which has values between -2 and 2, -2 being distractive and 2 being productive. With this data, we can generate a value over 100 for the productivity score.

Another API call to RescueTime,

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

Which gives you a weekly summary of your data, which looks like this:(look at summary.json at the end of this step.) I used this data to generate the weekly summary graph that gives you an overview of the week.

The Trello API call,

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

This will give you the cards on your Trello list like this:

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

again you can pull the text on those cards and put that on somewhere else.

data.json

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
],
view rawdata.json hosted with ❤ by GitHub

summary.json

[
{
"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"
}
]
view rawsummary.json hosted with ❤ by GitHub

Step 4: Prototyping

Now you have your data displayed on the monitor, it's time to design the mirror around your monitor. You have many designs to choose from, I used a light colored wood in my project since it was more compatible with my room.

There are really good magic mirror Instructables out there, check them out if you want to choose a different frame;

https://www.instructables.com/id/Smart-Mirror-by-R... by batynator

https://www.instructables.com/id/Raspberry-Pi-Smar... by HackerHouse

https://www.instructables.com/id/Magic-Mirror/ by khinds10

for my frame cut the wood by the dimensions:

Front:

  • 2x40cm
  • 2x47cm

Back

  • 2x38cm
  • 2x50cm

Step 5: Assembly: Wood&Mirror

Some Notes:

  • I used wood glue for the assembly, after putting the mirror inside the base I glued small triangle wood pieces to press the mirror into place. But after a while, I found out that wasn't a great idea. Because it created some space between the mirror and the monitor. So I do not recommend you to do that.
  • Before gluing the pieces, try to put the pieces around the monitor to see if there is any gaps or alignment issues.

Step 6: Assembly - Electronics (Optional LED)

Note: If you are building the basic setup and don't want the LEDs, you can skip this step.

The schematics and the LED control setup are from 2 separate tutorials that I used in conjunction. Go check them out!

How to control a RGB LED-Strip with a Raspberry Pi by David Ordnung

Raspberry Pi PHP LED controller by Christian Nikkanen

Important Note:

I've used the following pins:

  • GPIO17 for red
  • GPIO22 for green
  • GPIO24 for blue

If you want to use different pins, you have to change the pin numbers in the beginning of index.php

Step 7: First Test

At this point, everything should be working fine, but you still have to use a mouse and keyboard to start up your browser and type localhost on the address bar.

To open your browser and localhost on boot you have to do the following;

  1. Open up terminal and type:
sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart

2. Add the following line:

chromium-browser --kiosk  --incognito   "http://localhost/index.php"

Now you can disconnect your keyboard and mouse, your browser should start at boot and open up the index.php file.

Step 8: Troubleshooting

-I get an Error with the API's

  • API's used in this project have usage limits, if you are making too much requests than the API Key will limit your request thus you will get an error. To solve this issue add a delay to the refresh rate of the index.php file the default is set to 360 seconds.
#Seconds to refresh the webpage<br>$sec = "360";

-Browser does not work on startup

  • I provided the code to start the browser on boot, however, the location of the autostart file is different for each operating system version. The version I used is "Raspbian GNU/Linux 8.0 Jessie" you can check on StackOverflow with your info.

-The LEDs display a different color

  • Some LED strips on the market have different type of connections, most likely the color connection are mixed. You can correct this my connecting the cables to the their correct places. Also you can change the HEX value in the index.php file untill you are satisfied with the result.
if ($oran<50) {     $led->setHex("#FF0000"); }else {     $led->setHex("#00FF00"); }

you can use this HEX color calculator.

-I want to use different graphs to display the data

I used the chart.js javascript library for the graphs. You can follow their documentation for more:

http://www.chartjs.org/samples/latest/

Step 9: What's Next

This project is open for a lot of improvement, I did not have an additional budget for this build so I had to build with what I already had. Here are some things that I think should be improved or added:

  • A bigger screen: This way there would be a lot more space for different graphs and a part of the mirror so you can see yourself clearly.
  • Integration of different API's: There are a lot of different API's from a huge range of companies(twitter, google etc.), one idea that comes to my mind is the Spotify API. It could be integrated, so the music you are listening is displayed on the mirror. Here is a list of API's for brainstorming: https://www.programmableweb.com/apis/directory
  • Amazon Alexa voice control: I have an echo dot in my room, I can control the light in the room by voice. A fun and useful integration would be to use the voice control to change graphs on the mirror. "Alexa show daily summary" etc.

Well, I hope you enjoyed this project and learned a few things while building it. If you catch any mistake in the text or error in the code please let me know.

All questions are welcome!

You can also contact me at: gocivici@gmail.com