Skip to content

A web and voice universal remote interface for Raspberry Pi

License

Notifications You must be signed in to change notification settings

billpatrianakos/piremote

Repository files navigation

PiRemote

A web and voice universal remote interface for Raspberry Pi. This software will allow you to control any device that responds to IR commands using your voice and has a web interface that will allow you to control your devices from anywhere in the world that has an internet connection.

Requirements

Raspberry Pi - Any Raspberry Pi will do but the more powerful your Pi the more reliable your IR transmissions will be. The Raspberry Pi Zero W works fine. The Pi 3 works great.

LIRC - You need to install LIRC (Linux Infrared Remote Control) on the Raspberry Pi. If you're using a newer Pi (anything with the 4.X kernel) then follow these instructions to get LIRC working. LIRC is notoriously difficult to install on the Pi and after weeks of Googling I only found 2 resources that had the correct instructions for the new kernal so follow my Gist and you're guaranteed to have a smooth LIRC experience if you run Raspbian Buster.

IR transmitter and receiver - Any will do. You'll hook it up over GPIO. I used this pair which worked well and then tried this Pi HAT which also worked well. I like the second one because it has a slot to solder on a second IR LED which I did (this is the LED I used)

A static IP or domain - This project assumes Alexa will call the API on your Pi which means it needs to be connected to the open internet. My favorite way to do that is by creating a VPN tunnel to a server that I'm hosting other websites on and proxying the request to the Pi using Nginx. Check out this guide or this guide and here's some troubleshooting tips by me if you get stuck

An Alexa enabled device - Any Echo will do but you can also just use the app if you don't have one.

An IFTTT account - I use IFTTT to trigger events instead of doing things the longer harder way through creating custom Alexa skills. You can create a skill if you want but IFTTT gets the job done.

Setup

  • Install LIRC (follow the instructions linked to above) and install your IR transmitter and receiver (a transmitter is required but a receiver helps for creating your own LIRC config from any remote)
  • Set up a tunnel for using a custom domain using directions linked to above. This will set things up so that all requests to your publicly available domain will be forwarded to your Pi. You'll need to proxy requests sent to the public IP to your private network using Nginx's proxy_pass functionality. From there you can treat the entire application like it's hosted on your local Pi without thinking about the tunnel.
  • Create an IFTTT skill using Alexa and webhooks. You'll need one for each voice command you want to use. It's tedious but worth it. Create a new skill in IFTTT and choose the "Say a specific phrase" skill for Alexa for "if this" and then choose "Webhook" for the second part. Enter "mute" for example in the Alexa part and then for the webhook portion enter your domain and the API path /api/remote/command/ for the URL. You'll want to send it as a POST request with application/json as the content type. For the body you'll want to enter some JSON like this that matches each command name in your config/commands.js file: {command: 'mute',api_key: 'your_api_key_here'}. The command is the key name in the commands.js file. So in this case saying "Alexa trigger mute" will send the "mute" command which translates into irsend sending a 'KEY_MUTE' command from your IR transmitter.

Installation

Clone the repository locally

Clone this repo. I use a separate, private branch for deployment so my config files do not end up publicly available on GitHub. You can either do this as well or add your private config files to your .gitignore file.

Install dependencies on the Pi

  1. Install Nodejs v12.8.1. I use nvm to manage Node versions and the deploy scripts are written with that assumption.
  2. With Node installed, install global dependencies: npm install knex pm2
  3. Install Nginx: sudo apt-get update && sudo apt-get install nginx
  4. Install Postgres. Here's a good guide

TODO: explain setting up git repo on pi for deployment

Configure the PiRemote application

Now that you have the software required to run on the Pi installed, log out of the Pi and configure the application locally.

The following files need to be updated (All options that need updating are clearly marked with a value of CHANGE_ME. Doing a search for this string in the project folder will show you all the places where you can and probably should enter your own values):

  • system/piremote.conf - This is your Nginx config. Only you know how your Pi should serve the site. This is a good starting point.
  • system/interactionModel.example.json - OPTIONAL. If you plan to create an Alexa skill instead of hooking the app up to your IFTTT account then this is a starting point. You can safely ignore this file if using IFTTT.
  • config/application.example.js - Run cp config/application.example.js config/application.js to copy this file for use in your own project. Take a look at the production object and change your settings in there.
  • config/commands.js - This is a set of default commands you can use to get started. Just follow the template. Changing this file will update the UI of the remote interface automatically. Update this file with your default remote name and the time (in seconds) that you want the IR command to be sent. There are two modes: press and hold. Press is like a button press on the remote and you specify how many times you want the button to be pressed. Sometimes it takes multiple button presses for the appliance you're trying to control to respond so it's normal to have to use 2 or more button presses before your TV or cable box or whatever registers a single press of the button depending on your IR transmitter, how far from the receiver you place the Pi, etc. Hold mode is like holding down the button on a remote for X seconds. Like press mode, it can sometimes take multiple seconds for a key press to register. I personally use hold mode as it works best for my Xfinity cable box. It's easiest to just experiment with the irsend command directly rather than futz with configuring and reconfiguring and deploying the application over and over. You'll also want to set up your default remote to use for each key and also add any keys that aren't listed.

Deployment config

Run cp ecosystem.config.example.js ecosystem.config.js to get a production deployment config. Pay close attention to the post-deploy key. It assumes you are using Node via nvm. If your Node is in your PATH then you should adjust the first part of the setting export PATH=$PATH:/home/pi/.nvm/versions/node/v12.8.1/bin/ to match your environment. It's easiest if you just use nvm to install Node 12.8.1 and use the pi user to deploy. If you do this then you won't need to change anything except for the details of your Pi's IP address and the git repo that you want to deploy from.

Speaking of git repos, you probably don't want all your production config files in your GitHub repository if it's public. So what I do is create a branch off master called private (git checkout -b private) then create a private git repository (you can do this on GitHub or anywhere but I put the private repo on the Pi itself) and push your private branch to the private repository (git remote add private pi@your_pi_ip:git/piremote.git && git push private private for example). PM2 uses the remote and branch you specify to deploy so make sure whatever you use is updated with the latest configs from your branch.

Post deploy

You need to run the seeds to get the initial API key and user saved as there is no user sign up functionality now. Right now one user is created based on the default user you specified in your application.js. If you want more then just edit the API key and users seeds in config/db/seeds/production/ directly.

SSH into your Pi and run the seeds like this:

cd /path/to/piremote/current/
nvm use # if using nvm
NODE_ENV=production knex seed:run

Usage

Through the API

Send a POST request to /api/remote/command/ with JSON formatted like this example:

{
	command: 'mute',
	api_key: '10098153-38c3-4e53-be7b-cfa2cc21c7b4'
}

You can either choose to use a specific user's API key or use the generic one that's hardcoded into the application config. I personally use the generic one for API calls from IFTTT using the Alexa skill and webhooks and then use the current user's own API key for commands sent through the UI. This makes it so that you can deactivate API keys for specific users without disrupting usage by others in your house.

About

A web and voice universal remote interface for Raspberry Pi

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published