Workday Progressbar With Google Calendar Integration

by danionescu in Circuits > Raspberry Pi

5177 Views, 23 Favorites, 0 Comments

Workday Progressbar With Google Calendar Integration

Hands-on with Raspberry Pi Pico: Building a visual workday scheduler #electronics #raspberry
PXL_20230704_071026335.jpg
PXL_20230704_071026335.jpg
Productivity Hack: Progress Bar

I'm delighted to introduce you to a captivating project I recently discovered on GitHub, to which I'm now a proud contributor. The beauty of this venture lies in its simplicity and practicality. It offers a compelling way to visualize your entire workday, from sunrise to sunset, in your very own workspace.

Our primary tool for this creation is a microcontroller called Raspberry Pi Pico W. This mighty gadget teams up with Google Calendar to present your day's events on a LED strip. In my own experience, I've found that it integrates seamlessly with the aesthetic of my living space furniture. The end result is not just functional, but also an aesthetically pleasing addition to my room.

What makes this even more thrilling is the project's open-source nature. I was so drawn to the idea and execution that I didn't hesitate to roll up my sleeves and dive in as a contributor. My inaugural contribution was adding an easy WiFi setup, making the project even more user-friendly!

I wholeheartedly encourage everyone to embrace the open-source community. If you find a project that resonates with you, don't hesitate to contribute. It's a wonderful way to learn, grow, and make an impact on projects that inspire you.

The Build Steps

Let's dive into the impressive capabilities of this project.

At its most basic, the LED strip acts as a progress bar, taking you from the start of the day through to its conclusion using a hardcoded configuration. In this fundamental setup, there's no need for any integration with Google Calendar.

For a more enriched experience, an advanced configuration allows you to set up a public calendar that interacts directly with the Pi Pico. With this in place, the start and end times of your day, along with all the events, are directly fetched from Google and visually represented on your LED strip.

Here are the steps we'll be walking through:


  1. The Build Steps
  2. Gathering the materials and tools: Getting everything you need in place.
  3. Preparing the Pi Pico: Uploading the necessary code onto the microcontroller.
  4. How Does The Code Work? Explaining the code
  5. Configuring Google Calendar Integration: This is an advanced, optional step that allows for even more personalized display.
  6. Wiring And Creating The Device: Setting up the hardware components.
  7. Future Improvements and Motivation: Discussing potential enhancements and the driving force behind the project.


Join me on this journey of creation, and let's breathe life into this beautiful project together.

Gathering the Materials and Tools

materials1.jpg

Tools:

Solderin iron

Laptop

Wire cutters

USB - C to USB - A cable for programming the Pi


Materials:

Raspberry Pi Pico W

5V Addressable LED strip (we used a 1 m, 144 LED, WS2812B Eco).

USB charger with USB-C cable ( >= 1 A )

Aluminium led profile

Various wires

Plastic enclosure for the Pi


Skils:

Basic soldering skills

Experience with dev boards: installing software, uploading code, modifying files

Optional: Configuring Google cloud API

Preparing the Pi Pico

PXL_20230708_083653980.jpg
Screenshot from 2023-07-08 11-59-21.png
Screenshot from 2023-07-08 12-06-31.png
phone2.png
phone1.png

In this section, we're going to address how to update the firmware on your Raspberry Pi Pico W board, install the necessary software, and upload the code for the project.

  1. After acquiring your Raspberry Pi Pico W, your first step is to install the most recent firmware on the board. The Raspberry Pi Foundation provides an excellent guide on how to do this. All you have to do is follow the instructions here.
  2. Next, you'll need to download Thonny, an accessible tool for editing and uploading code to your board. You can download it from here. It is compatible with Linux, Windows, and Mac operating systems.

With the groundwork laid, it's time to acquire the project code from GitHub. For Linux users, I'll provide a step-by-step guide, assuming you already have git installed on your system.

cd ~
git clone https://github.com/veebch/hometime.git
cd hometime
git checkout a7f061caabb1aeede6bdeb07b33bb97bfbb6a420
mv config_example.py config.py

Explanation:

  • Navigate to the home directory.
  • Clone the repository locally.
  • Change directory to "hometime," the cloned git repository.
  • Set the repository to a specific commit in time (one that I've tested and confirmed works). If you're feeling adventurous, you can omit this step to try the latest version.
  • Rename 'config_example' to 'config'. The code uploaded to the board expects to see a file named "config.py."

3. Next, modify the config.py according to your requirements.

In a basic configuration, we'll manually set the working day start/end hours. This means we'll omit the "CALENDAR" and "APIKEY" values and ensure "GOOGLECALBOOL" is set to False. A separate step is dedicated for integrating with the Google Calendar API.

  • Set your timezone "TIMEZONE". The default is "Europe/Zurich"; choose one from this list.
  • Choose the number of LED pixels "PIXELS". Note: if you have the default one-meter LED strip, leave the default as 144.
  • Set the "GPIOPIN" for controlling the LED strip.
  • You can also set RGB values for the bar "BARCOL", and events "EVENTCOL".
  • If you need the strip to display from right to left, set "FLIP" to True.
  • In the "SCHEDULE" config dictionary, change (if you like) the 'clocking' and 'clockout' values for each day.

With the configuration set up, you're ready to bring your visual workday schedule to life.

4. Upload the code

  • Plug in the Pico W into your laptop.
  • Check that the serial port has permissions for your current user.
  • In Linux, you can simply use 'ls', then look for something like /dev/ttyACM0 or /dev/ttyUSB0.
ls -l /dev/tty*
....
crw-rw---- 1 root dialout 166, 0 iul 8 11:44 /dev/ttyACM0
...
  • Open Thonny IDE

If you can't locate Raspberry Pi Pico at the bottom left of the screen, you may need to adjust the permissions for the dialout user. To do this, replace <username> with your current Linux logged-in username.

sudo usermod -a -G dialout <username>


  • Within Thonny, navigate to the location where you cloned your repository.
  • Select 'ap_templates', 'phew', 'config.py', 'main.py' using Ctrl, then right click on the selection and choose "Upload to /".
  • To start the program in debug mode, simply click on "main.py" from the "Raspberry Pi Pico" section at the bottom left (refer to the accompanying images for more detail). You should then see something similar to the following in the log:
MicroPython v1.20.0 on 2023-04-26; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>> %Run -c $EDITOR_CONTENT
Entering setup mode...
2023-07-08 12:05:52 [info   / 152kB] > starting catch all dns server on port 53
2023-07-08 12:05:52 [info   / 149kB] > starting web server on port 80
run for 18000
  • If you see this message, it indicates that the Pi has booted correctly, and it has started its own access point to which you can connect and set Wi-Fi credentials for your router. The access point name is "Pi Pico". If you're using your phone, you might need to disable mobile data, as this can sometimes interfere with the local Pico network (because it doesn't provide internet; see photos for reference).
  • When you click on the Pi Pico network, it should redirect you to a browser session. If not, please navigate to "pipico.net".
  • Next, set your SSID and Password in the setup browser window, then click "Save". The Pico will reboot and attempt to connect to your Wi-Fi network.
  • On the serial debugger in the Thonny editor, you should see something like:
023-07-08 16:01:50 [debug  / 125kB] > parsed template: ap_templates/redirect.html (took 8 ms)
2023-07-08 16:01:51 [info   / 123kB] > POST /chat (200 OK) [133ms]
Saving wifi credentials...
2023-07-08 16:02:00 [debug  / 141kB] > parsed template: ap_templates/configured.html (took 10 ms)
2023-07-08 16:02:00 [info   / 139kB] > POST /configure (200 OK) [418ms]
2023-07-08 16:02:00 [debug  / 129kB] > parsed template: ap_templates/redirect.html (took 9 ms)
2023-07-08 16:02:00 [info   / 126kB] > GET /generate_204 (200 OK) [222ms]
2023-07-08 16:02:00 [debug  / 149kB] > parsed template: ap_templates/redirect.html (took 17 ms)
2023-07-08 16:02:00 [info   / 147kB] > GET /generate_204 (200 OK) [227ms]
Resetting...
Connection lost (device reports readiness to read but returned no data (device disconnected or multiple access on port?))

Use Stop/Restart to reconnect.
  • If you reconnect the serial port now, you should see the Pico connected to the Wi-Fi. At this stage, something like this should be displayed in the serial. Concurrently, the LED strip will initiate with a rainbow pattern before displaying the progress bar.
MicroPython v1.20.0 on 2023-04-26; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>> %Run -c $EDITOR_CONTENT
2023-07-08 17:24:27 [debug  / 151kB]  - got ip address
Connected to wifi, IP address 192.168.1.110
Entering application mode.
Connected to WiFi
Rainbow!
Turn off all LEDs
Grab time: https://timeapi.io/api/TimeZone/zone?timezone=Europe/Bucharest

setting time
Begin endless loop
Updating from Google Calendar
['2023-07-07T09:00:00+03:00', '2023-07-07T09:15:00+03:00', '2023-07-08T09:00:00+03:00', '2023-07-08T09:30:00+03:00', '2023-07-08T19:00:00+03:00', '2023-07-08T19:30:00+03:00']
['2023-07-07T09:00:00+03:00', '2023-07-07T09:15:00+03:00', '2023-07-08T09:00:00+03:00', '2023-07-08T09:30:00+03:00', '2023-07-08T19:00:00+03:00', '2023-07-08T19:30:00+03:00']
clockin: 9.0
True 9.0 19.5 17.41333
Pour yourself a cup of ambition
...

How Does the Code Work

Main logic:

  • The try-except block determines whether there is a WiFi configuration file present.
  • If the file is found, it attempts to connect to WiFi using the credentials stored in the file.
  • If the connection is successful, it enters the application mode.
  • If the connection fails or an exception occurs, it enters the setup mode.

In the application mode loop:

  • The code retrieves the current time from a web API using the set_time function. It parses the response, extracts the relevant date and time components, and updates the internal RTC (Real-Time Clock) of the microcontroller.
  • The code determines the current day of the week using the whatday function.
  • If the googlecalbool flag is set to true, the code retrieves today's appointment times from a Google Calendar using the get_today_appointment_times function. It sorts and stores the appointment times.
  • The code checks if the current day is a working day based on the configured schedule or the Google Calendar events. It uses the atwork function to determine if the current time falls within the working hours.
  • If it's a working day, the code adjusts the NeoPixel strip to display a progress bar representing the current time within the working hours. The bar function is responsible for setting the colors of the LEDs on the strip accordingly.
  • The code checks if there are any Google Calendar events happening at the current time using the eventnow function. If there is an event, it sets the eventbool flag to true.
  • If the current time is close to the end of the working hours (within 10 seconds), the microcontroller is reset using the machine_reset function to prepare for the next day.
  • If the flip flag is enabled, the code flips the orientation of the progress bar on the NeoPixel strip using the flipit function.
  • The code periodically checks for updated Google Calendar events to keep the progress bar synchronized. It resets the check counter (googleindex) after a certain number of iterations (checkgoogleevery).
  • The NeoPixel strip is updated with the new LED colors, and the code waits for 1 second before the next iteration of the loop.

In the setup mode:

  • The code sets up a local access point (AP) and a web server to allow users to configure the WiFi credentials for the device.
  • The AP name, domain, and template paths are defined.
  • The code defines several routes for the web server, including an index route (ap_index), a configuration route (ap_configure), and a catch-all route (ap_catch_all).
  • The ap_index function renders the index HTML template for users to enter their WiFi credentials.
  • The ap_configure function saves the entered WiFi credentials to a file and triggers a reboot of the microcontroller to apply the new configuration.
  • The ap_catch_all function handles any other routes and redirects to the AP domain if necessary.
  • The AP is started with the defined settings, and the web server is run.
  • Users can connect to the device's AP, access the provided web pages, enter their WiFi credentials, and submit them for configuration.
  • Once the configuration is completed, the microcontroller reboots and enters the application mode with the newly configured WiFi credentials.


Configuring Google Calendar Integration

Screenshot from 2023-07-05 11-30-21.png
Screenshot from 2023-07-05 11-31-36.png
Screenshot from 2023-07-05 11-34-56.png
Screenshot from 2023-07-05 11-35-24.png
Screenshot from 2023-07-05 11-36-46.png
Screenshot from 2023-07-05 11-38-48.png
Screenshot from 2023-07-05 11-39-17.png
Screenshot from 2023-07-05 11-39-48.png
Screenshot from 2023-07-05 11-40-02.png
Screenshot from 2023-07-05 11-41-28.png
Screenshot from 2023-07-05 11-43-27.png
Screenshot from 2023-07-05 11-43-50.png
Screenshot from 2023-07-05 11-50-14.png
Screenshot from 2023-07-05 11-51-01.png

The truly captivating aspect of this project is its integration with Google Calendar. This feature, however, requires additional steps and the use of a "public calendar." Essentially, you'll need to create a separate public calendar on a Google account. Though this means anyone can view its events, the upside is that you can remotely configure the start/end time of each day and display these events on your LED strip.

Follow these steps to set it up:

  1. Log into your Google account in your browser.
  2. Open Google Calendar: https://calendar.google.com/calendar
  3. Click on "Other calendars," then "Create new calendar."
  4. Set a name and description for your new calendar, then click "Create Calendar."
  5. Click on the three dots beside the calendar name on the left bar, then select "Settings and sharing."
  6. Check the box for "Make available to public."
  7. Scroll down and copy the "Calendar ID" for later use.
  8. Open https://console.cloud.google.com/projectselector2/apis/dashboard
  9. Click on "Create project," set a name for the project, and click "Create."
  10. On the project page, search for "calendar" API, click on "Google Calendar API," then click "Enable."
  11. Go to "Credentials," select "Create Credentials," then "API Key," and copy this key for later use.
  12. Return to the Google Calendar page https://calendar.google.com/calendar and add two recurring events for each day: a "start day" event from 9:00 to 9:05, and an "end day" event from 17:00 to 17:05.
  13. Test the integration using curl commands in a Linux terminal. Replace the placeholders in the first few lines with your actual values:


API_KEY="YOUR_API_KEY"
TIME_MIN="2023-05-21T00:00:00Z"
TIME_MAX="2023-05-28T23:59:59Z"
CALENDAR_NAME="YOUR_CALENDAR_ID"
encoded_calendar_name=$(echo "$CALENDAR_NAME" | sed 's/ /%20/g')

curl "https://www.googleapis.com/calendar/v3/calendars/${encoded_calendar_name}/events?key=${API_KEY}&timeMin=${TIME_MIN}&timeMax=${TIME_MAX}"


it should return a json like:

{
 "kind": "calendar#events",
 "etag": "\"p33sff2nrivrvu0g\"",
 "summary": "Hometime",
 "updated": "2023-07-05T08:50:54.763Z",
 "timeZone": "Europe/Bucharest",
 "accessRole": "freeBusyReader",
 "defaultReminders": [],
 "nextSyncToken": "CPj3ivuX9_8CEAAYCiDR6oaDAg==",
 "items": [
 {
  "kind": "calendar#event",
  "etag": "\"3377094035406000\"",
  "id": "7mo82l9d0ggad882ua6t3gcash_20230705T060000Z",
  "status": "confirmed",
  "htmlLink": "https://www.google.com/calendar/event?eid=N21vODJsOWQwZ2dhZDg4MnVhNnQzZ2Nhc2hfMjAyMzA3MDVUMDYwMDAwWiBjX2QzODM0YTc4YzQ0NDE3OTIyMTBkNWNmMTRlNjRhMTAzNzRkNDUxYzQxMzdkM2EwNTFjMGU5MjQzMWFjNTQ1OWJAZw",

...


14) Modify the following lines from config.py and upload them tho the pi

CALENDAR = "your calendar id"
APIKEY = "INSERT YOUR APIKEY"
...
GOOGLECALBOOL = True    # ensure this is set to True
...

Wiring and Creating the Device

schematic_bb.png
PXL_20230708_164004783.jpg
PXL_20230708_164032961.jpg
PXL_20230708_164119689.jpg
PXL_20230708_164152832.jpg
PXL_20230629_143944755.jpg
PXL_20230630_041941938.jpg

For the wiring, the process is quite straightforward:

  1. Connect the USB cable from the charger to the Pico.
  2. Next, you need to identify the LED strip pins. My strip has a (-) sign for one of the wires (which, unfortunately, isn't black), along with another red wire (which I assumed was +) and a different color wire that I assumed was the signal. This is the tricky part because I didn't have any instructions for it. Fortunately, my assumptions were correct.
  3. Connect the Pi's VBUS to the LED strip's (+).
  4. Connect one of the Pi's (-) to the LED strip's (-).
  5. Connect the Pi's 15th pin to the LED strip's signal pin. Please note that GPIO pin 15 is the 20'th pin. Please consult the pdf pinout file

At this point, the LED strip should light up (provided it's within the correct hour intervals).

I measured the power consumption with a multimeter, and it's less than 500mAh. Note that the VBUS does not pass through the Pico—it draws directly from your USB charger. Ensure that the charger can deliver more than 500mAh to be on the safe side.

Then, I soldered some longer, thinner wires from the Pico to the LED strip and placed the Pico inside a plastic enclosure, which I hid behind my TV. I then attached the aluminium LED profile with the strip onto my furniture and masked the whole setup.

Don't forget to consult the pictures :)

Future Improvements and Motivation


I was captivated by this project the moment I saw it, so I decided to replicate it myself. Wanting to improve it—starting with the WiFi configuration part—I forked the repository and pushed the code. I am grateful to the repository owner for their promptness and proactiveness.

While this is not my original idea, I greatly appreciate open-source work and wanted to create a tutorial for this project. My hope is that this will make it easier for others to recreate this project. I also encourage you to do the same with ideas that pique your interest.

Possible enhancements for this project could include creating a web-based setup for full configuration, and finding an alternative method for connecting to Google Calendar so that it doesn't need to be public.

I hope you find this as exciting as I do!

For more of my intriguing projects, please visit my GitHub profile: https://github.com/danionescu0

For some fun projects by veebch (the original creator of this project), check out: https://github.com/veebch