Google Calendar Printed on Receipt Paper

by __Alex__ in Circuits > Raspberry Pi

123 Views, 1 Favorites, 0 Comments

Google Calendar Printed on Receipt Paper

IMG_6304.jpg
IMG_6305.jpg
IMG_6306.jpg

This is a small device that will print out information from your google calendar, onto receipt paper. Every morning, the device checks for each event happening in your calendar that day, and formats it onto a piece of thermal paper. With this, you can always stay on top of your day without needing to check your phone!


The heart of this project is the thermal printer. The same kind used in stores and restaurants, it prints on a special kind of paper that darkens wherever heat is applied. This way, information can be printed using only electricity, with no ink and almost no moving parts.

Then a Raspberry Pi, a small programmable computer, can run a python script that will check for events in your calendar using the Google Calendar API, and put all that information into a text file. From there the text file can be printed on the thermal paper using the CUPS printing software. Using Cron, the Raspberry Pi can automatically call the script every morning at a set time, and with that you'll have a receipt in the morning with everything you have going on that day, without needing to touch a single button!

Supplies

IMG_6381.jpg

Parts:

Thermal Printer, includes 2 3-pin JST cables for serial and power.

Raspberry Pi computer

USB Keyboard, Mouse, Display

5 jumper wires with Female end

Heat-Shrink or Electrical Tape


The exact printer from this build is currently discontinued on Adafruit, however any serial printer compatible with Raspberry Pi can be used.


Tools:

Wire Cutter/Stripper

Soldering Iron

Digital Multi Meter (DMM)

3D Printer

Dremel or low-grit Sand Paper



PLA printer filament is recommended for the housing, but any kind should work.

Wiring

Screenshot 2025-08-11 180151.png
IMG_6379.jpg
IMG_6380.jpg
components_raspberry_pi_gpio-diagram.png
IMG_6377.jpg
components_test-baud.jpg

For more general instructions that applies to other printers, check out this Adafruit guide on connecting thermal printers, which covers Arduino, Raspberry Pi, and PCs.


First, you need to splice the 3-pin JST cables provided with the printer to jumper wires that can connect to the Raspberry Pi's GPIO pins. For this printer, there is one cable for power, and one for TTL serial as pictured above. Since the printer and serial line can both operate at 5V, they can be plugged directly into the GPIO pins on the Raspberry Pi without the need for a separate power supply.

Cut each JST cable in half with the wire cutters. Then with one side of the power and serial cables, expose around ~1/4" of metal on each wire. Do the same for the 5 Jumper wires. Once all of the wires have been prepared, solder the jumper wires to the JST wires.

Next, use the DMM to check for a small resistance reading across each wire, from the JST side to the jumper side. There should be a measurable reading between the two wires. If the resistance is to great to measure or fluctuating by a large amount, then the solder joint is not very strong and should be remade. Do this before sealing the connection to make sure all of the solder joints are strong and conducting properly. Finally, use either heat-shrink or electrical tape to isolate the wires from each other.


Before plugging anything into the Raspberry Pi, make sure that it is configured for TTL serial. To do this, go to Preferences > Raspberry Pi Configuration > Interfaces. Make sure Serial Ports is ON, and Serial Console is OFF.


Now that the cables are ready, it is time to plug the printer into the Raspberry Pi. Start by making sure the two JST cables are plugged into the printer, so that the green/yellow/black cable is in the RX&TX port, and the red/black cable is in the DC IN port. Plug the red wire from the printer into any 5V pin on the Raspberry Pi, and the two black wires into any Ground pin. Make sure that the wire labeled TX on the printer goes into the GPIO pin labeled RX, and vice versa. Next, plug in the Raspberry Pi. If the printer is receiving power, a green light should go up on the front of the printer.

To check everything is working properly, print a test-page. For most thermal printers, hold down the button on the front of the printer for several seconds and release. If this doesn't work, check the manual for your printer. A long page should begin to print, with information about the printer and the connection to the computer. Look for the baud rate of the printer, this is needed in the next step.

Configuring Printer


Now that the printer is on, it is time to configure it on the Raspberry Pi. Instead of manually talking to the printer over serial, The CUPS library will allow you to easily send print jobs from the Raspberry Pi, using a premade configuration for a similar thermal printer.


Once your Raspberry Pi is on, open a command line. Check for updates and install CUPS with the commands:

>Sudo apt update
>Sudo apt upgrade
>Sudo apt install cups

Next,

Go into the printers menu at the top of the screen and setup the printer 'ZJ-58'. Make sure when creating the device that you specify the correct baud rate of your printer. If you do not know it, assume it is 9600Baud. The ZJ-58 library is a thermal printer library that will allow the Raspberry Pi to print out text files onto the thermal printer using only the lp command. To test this worked correctly, make a text file text.txt and put any text into it. Then print it with:

lp text.txt

You should see a print job queue, and after a few moments the printing should begin!


Connecting API

For a more detailed breakdown on this step, follow this tutorial on the Google Developer site.

For this step, make sure your Raspberry Pi has python installed, and you have a google account with a calendar to pull from.


First, enable the Google Calendar API on your account. This allows a device with permission to read or write data from your google account's calendar. If you haven't used a google cloud project before, you will also need to setup Google OAuth consent. To configure OAuth consent, follow the link to the tutorial at the top of this step.

Next, you need to create credentials for your Raspberry Pi to be allowed to access your calendar. Open your Google Clients List, and click Create Client. Then select the Desktop App client type, and click Create. Next save the credentials.json for this client. This JSON is what will allow your Raspberry Pi to access your Google Calendar. Copy this file to the place with the other files for the project, and make sure it is always in the same folder as the script attempting to access your calendar.


Now it is time to write the python script. Install the necessary libraries with:

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

Next try running the official Google Calendar API quickstart script, which will attempt to get your next 10 calendar events from your primary calendar, and print them onto the terminal along with their start times (in ISO datetime).

import datetime
import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]


def main():
"""Shows basic usage of the Google Calendar API.
Prints the start and name of the next 10 events on the user's calendar.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists("token.json"):
creds = Credentials.from_authorized_user_file("token.json", SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
"credentials.json", SCOPES
)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open("token.json", "w") as token:
token.write(creds.to_json())

try:
service = build("calendar", "v3", credentials=creds)

# Call the Calendar API
now = datetime.datetime.now(tz=datetime.timezone.utc).isoformat()
print("Getting the upcoming 10 events")
events_result = (
service.events()
.list(
calendarId="primary",
timeMin=now,
maxResults=10,
singleEvents=True,
orderBy="startTime",
)
.execute()
)
events = events_result.get("items", [])

if not events:
print("No upcoming events found.")
return

# Prints the start and name of the next 10 events
for event in events:
start = event["start"].get("dateTime", event["start"].get("date"))
print(start, event["summary"])

except HttpError as error:
print(f"An error occurred: {error}")


if __name__ == "__main__":
main()

The first time you run this code, it should fail, saying that you need to authenticate the device, and spits out a link in the terminal. Open the link from the terminal in a web browser and sign in to your google account, and authorize the device. Rerunning the script, you should now get the desired output.

Modification & Automation

Modifying the python program

Optionally, you can also set the script to pull events from a specific calendar, instead of your default calendar. To pull from a specific calendar, first open google calendar. The click on the 3 dots next to the calendar you want to print from. Click on Settings and Sharing. Next, scroll down to the Calendar ID. This should be in the form of a long link. To access this calendar from the python script, replace 'primary' with the link, like this:

calendarId="primary", #Original line
calendarId='12345@group.calendar.google.com', #new line

Now, instead of getting 10 upcoming events, we want to find all of the events within 24 hours. To do this, use the 'timeMax' keyword in the API call:

events_result = service.events().list(calendarId='primary', timeMin=now,
timeMax=tomorrow,
singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])

Next, instead of printing the information to the terminal, change the output to a .txt file, with the code:

with open('/home/pi/PrinterScript/output.txt', 'w') as f:
print('now[5:10], file=f)
for y in range(0,numEvents):
print (times[y], file=f)
print (' ' + str(names[y]), file=f)
print('', file=f)

Make sure that you import the ability to write to files this way with:

import os.path

In the top of the program. All that's left is to call the printer from within the program, with the line:

os.system("lp /home/pi/PrinterScript/output.txt")

Where lp calls the printer to print out the text file you just generated.

For reference, I attached my version of the code as PrinterScript.py.


Automation

Next, it is time to automate this program with Cron. Cron is a feature on Linux systems that lets you automatically call a script any a specific interval. However, Cron cannot directly call the python file so we need to make a shell script which can call the python script, and be called by Cron. To do this, make a .sh file (like script.sh) that contains the following:

#!/bin/bash
cd /home/pi/PrinterScript
python UpdatedPrint.py

Where #!/bin/bash is the location of your bash shell, /home/pi/PrinterScript is the location of your python file, and UpdatedPrint.py is the name of your python file. Once this file has been made, make sure it is executable with the line:

chmod +x dailyCalendar.sh

Lastly, check that this script works properly by running the .sh script in the command line:

./script.sh

You should get the output of the python file. Make sure that the names/locations of all the files reflect your project, as they won't necessarily be the same as mine.


Once that's all working, just open Cron with:

crontab -e

and, to for example run your code every morning at 8am:

0 8 * * * /path/to/your/script.sh

In order, 0 8 * * * represents the minute, hour, day of month, month, and day of week that the script should be called.


Now that the Raspberry Pi is all set, it's just time to put it into an enclosure.

Downloads

Enclosure

IMG_6386.jpg
IMG_6387.jpg
IMG_6385.jpg
IMG_6383.jpg
IMG_6384.jpg
IMG_6382.jpg
Screenshot 2025-08-19 144726.png

(3D) Printing the Case

Now that the printer is all setup with the script to automatically collect calendar data, it is time to finish it up with a case. As long as the Raspberry Pi has an internet connection, the script can run without needing any peripherals besides power. The case mounts the printer in the front, and Raspberry pi below for a compact profile. The front plate of the printer opens outward to replace thermal paper, so it is not necessary to get into the case when paper runs out. There is a lid on the top to easily unpack the circuit if changes are desired.

To print the case default settings on a 3D printer should work fine, just make sure that supports are generated for the overhangs in the front and back. I printed this on a P1S printer with a generic PLA filament, but this print should be easy for any combination of printers and filaments.

A tight fit between the printer and case ensures nothing will fall loose, so the opening in the STL file is slightly undersized. To test the fit, insert the printer through the opening on the case without any wires attached. If it is too difficult, sand the opening a little larger using sandpaper or a Dremel with a sanding drum. Alternatively, if the fit is too loose and the printer wont stay in place, use glue around the edges of the printer to mount it at the final step.


Assembly

For final assembly, disconnect the Raspberry Pi from power, and the printer from the JST cables. Feed in the power cable from the back of the case, and plug it into the Raspberry Pi. Then place the Raspberry Pi on the bottom of the case, and let the excess length of power cable back out of the hole. Feed the JST cables through the front of the case, and plug them back into the printer. The simply push the printer backwards into the opening.

Once the printer is pushed into place, all you need to do is drop on the top and you're all set! You now have a device that automatically prints your calendar every morning.