Cheap Alexa Printer From An Old Receipt Printer

Upcycle an old receipt printer into a voice assistant/Internet of Things printer!

Connecting to the Internet of Things (Part 1)

What good would a printer be without something to print? I wanted to enable functionality to print from different internet services. One option is to choose a specific internet service, track down their API documentation and write an application based on their API. But I choose to go the lazy route…

There's a great website called β€œIf This Then That” which triggers actions for different internet services (Alexa, Google Home, Gmail, Facebook, Instagram, Twitter, etc) based on a set of criteria. For instance, β€œif” I post to Facebook (this), β€œThen” send me an e-mail (that).

So for the first half of this, I signed up for a free account, you can start creating a new β€œapplet” for the different services you want to trigger. The β€œThis” part of my applet will be Alexa. There are a lot of Alexa triggers to choose from, but I'm going to select the one that says β€œAsk what's on your shopping list”. And we ultimately want it to trigger a Python script on the Raspberry Pi, so for the β€œThat” portion of the script, we want to choose Webhooks.

In the Webhooks option, we can add a URL that points to our Pi, which we'll come back to later. We can leave the Method field as β€œGet”, and for the content type select β€œPlain Text”. For the Body field, click β€œAdd Ingredient” and select β€œEntire List”. This will send the entire shopping list as a Get request.

The previous step takes care of the β€œInternet” part, so now lets work on the β€œthings” part using the Raspberry Pi. In order to communicate with the β€œIf This Then That” webhooks applet, we need to set up a web server on the Raspberry Pi. There are many different ways to set up a web server, but considering I ultimately want to run a Python script, I decided to use Python's Flask server.

The Pi has all the Flask libraries pre-installed, so all we need to do is start writing a test script:

nano flask_test.py

And in it, let's add some code that serves a simple web page.

#!flask/bin/python
#IMPORT THE FLASK LIBRARIES
from flask import Flask, request
#CREATE A FLASK VARIABLE
app = Flask(__name__)
#CREATE AN 'INDEX' PAGE
@app.route('/')
def index():
return 'Your Flask server is working!'
#RUN THE PROGRAM
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0' )

Now just save the program and run it using this command:

sudo python3 flask_test.py

You'll see by the command response that the default port that Flask runs on is port 5000. So in a web browser, if you type in your Pi's IP Address:5000, you should see the text β€œYour Flask server is working!”

nano iot_print_server.py

And within it, add the following code:

#!flask/bin/python
#IMPORT THE FLASK AND PRINTER LIBRARIES
from flask import Flask, request
from escpos.printer import Usb
#ASSIGN VARIABLES FOR THE PRINTER AND FLASK
p = Usb(0x0416, 0x5011)
app = Flask(__name__)
#CREATE 'INDEX' PAGE
@app.route('/')
def index():
return 'Your Flask server is working!'
#CREATE "PAGE" CALLED "LIST" FOR PRINTING ALEXA SHOPPING LIST
@app.route('/list')
def list():
#CAPTURE "GET" DATA FROM IFTTT WEBOOKS
content = request.get_data()
#CONVERT RAW DATA TO STRING
str_content = str(content)
#DIVIDE DATA INTO SEPERATE LINES
str_split = str_content.splitlines()
#SEPERATE WORDS BY COMMA AND ADD TO A NEW LIST
newlist = []
for word in str_split:
word = word.split(',')
newlist.extend(word)
#REMOVE FORMATTING MARKS
rmv_marks = [s.strip("b'") for s in newlist]
#PRINT HEADER
#print("Shopping List\n")
p.text("Shopping List:\n")
#ENUMERATE AND PRINT EACH ITEM IN LIST
r = 1
for x in rmv_marks:
#print(str(r) + ". " + x + "\n")
p.text(str(r) + ". " + x + "\n")
r += 1
#RETURN RESULTS
return 'x'
#RUN THE PROGRAM
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

You can run it to see if it returns any errors, but it won't work with our webhook yet because as of right now, the server is only running locally. There's no external URL for the webhook to connect to yet. We could set up port forwarding on our router and just use our external facing IP address, but that's not really too secure. As an alternative, I decide to go with NGROK.

Setting up External Access with Ngrok

Ngrok sets up a secure connection to your network without having to expose your external IP or mess with port forwarding. After signing up for a free account, it gives you an authorization token. Then on your Raspberry Pi, you can download it, unzip it, connect your auth token, and then run it on port 5000:

mkdir ngrok
cd ngrok
wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip
unzip ngrok-stable-linux-arm
./ngrok authtoken [insert your auth token here]
./ngrok http 5000

***IMPORTANT***

The free version of Ngrok doesn't give you a static address, so everytime you re-run Ngrok, it'll give you a different address. If you want a static address so that you don't have to keep re-editing your Webhook, then you'll need to pay for an upgraded account.

************************

On the resulting screen, it gives you a forwarding address (http://random-string.ngrok.io) that you we can use in our Webhook applet. So going back to β€œIf This Then That”, in the URL field, enter your Ngrok forwarding address and point it to the β€œlist” page on our Flask server. It should look something like this

http://random_string.ngrok.io/list

Then go ahead and save the changes.

To test it out, keep Ngrok running, open up a new terminal, and run our python script. With both items running, ask Alexa what's on your shopping list. After a minute or two, it should print out the results. If you want it to print immediately, just go to your Applet on IFTTT and click β€œCheck Now”. If everything goes well, the receipt printer should print out what's on your shopping list!

The final bit of code we need to add is a way to autostart ngrok and our flask server every time the Pi starts up. We can easily do that by making our Python script executable:

chmod +x iot_print_server.py

Then we can edit our /etc/rc.local file so that it looks like this:

#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
#autostart ngrok and point it to your auth file
./home/pi/ngrok/ngrok http -config=/home/pi/.ngrok2/ngrok.yml 5000
#autostart the printer python script
sudo python3 /home/pi/iot_receipt_printer.py &
exit 0

Adding the Pi to the Printer

The receipt printer I have has a lot of empty space inside the casing. And with the Raspberry Pi Zero being as small as it is, I thought it'd be cool just to hide it in the receipt printer so that it looks like one device. The only problem is that the Receipt printer runs on 12v and the Pi runs on 5v. So if we only want one power cable to power both of them, we're going to have to step down that 12v power supply to 5v.

Using a 7805 voltage regulator, a 1uf capacitor, and a 10uf capacitor, I was able to create simple 5v regulator that I connected to the logic board of the receipt printer. I soldered the β€œ-” wire to the common ground, and then I soldered the β€œ+” wire to the β€œon” side of the power switch so that the Pi would turn on and off when the printer was turned on and off. Using a multi-meter, I tested to confirm that the output was safe for the Pi. Then I soldered on a micro-usb cable and connected it to the Pi. After plugging the cable into the printer and flipping the switch, both the printer and the Pi turned on!

Finally, I drilled a hole to connect the USB cable from the Pi to the printer. I found a place to put the 5v regulator and Pi inside the printer case, and then I put everything back together. So now the printer has it's own self contained web server as well!

Taking It Further

If you were able to take a look at β€œIf This Then That”, you probably noticed that it has tons of different web services to connect to. So if you don't have an Alexa, or don't care to use one, you can use this project to print from just about anything, such as Facebook, Twitter, Gmail, Google Home, Evernote, Tumblr, Flickr, WordPress, etc. Now go and see what you can come up with!


About The Author

Muhammad Bilal

I am highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top