Build your own Pi-Powered TV Recording System

If you are a Pi-addict like me, I’m sure you were extremely happy like I was, when was announced few months ago, the official Raspberry Pi TV HAT. At the same time, my ISP announced a new upcoming setup box, meaning that I had to initiate the “retrieval” of all TV recordings out of my existing setup. Because of the “security” set on them (you know, if you record it through ADSL it’s protected, but if you record it through your DVB receiver it’s not), that process really made me realize that it was time to get out of any ISP proprietary system.

Time to gather the troops

It wasn’t long before ordering one of the hats and to get it ready to go with a new Raspberry Pi3 and assorted cooling components.

Pi3, cooling parts & most expected DVB TV Hat

The TV hat set is complete with aerial adapter, Pi supports and GPIO header to make it fit properly on top of the Pi. As it is supposed to fir as well a PiZero form-format, the set would please all Pi aficionados.

As I was lucky enough to have some WD Pi-Drive parts (too bad they had been discontinued :( ), once completed by the TV Hat, they would be perfect to create the recording station. There were 2 models of WD Pi-Drive enclosures, small and big, but the big version was impossible to get anywhere (at least for a reasonable price) : that’s OK, as the small unit kinda reminds me of another “fruity” TV box. All that it requires is just a little touch of color to complete the enclosure.

Mounted and “labelled” Pi TV Setup box

Nicely organized, the official WD Pi-Drive keeps everything in place… but actually a little bit “too much”!

Indeed, once the Pi3, the official hard-drive and the associated cables in place, there is no space to add our TV Hat.

Also, considering the positioning of the GPIO port, we are facing 2 issues. First, the orientation of the GPIO would require from the aerial connector to be facing the front of the box, which would not be very nice and practical. Also, as the Pi3 and the hard-drive are right on top of each other, there is actually no space to put the TV Hat in such a confined area. Therefore, an alternative must be found for the hat to be installed.

You can keep your (TV-)Hat on after all

After some additional research, one alternative came up in order to install the TV-Hat. You can find extension GPIO ribbons that include not just female-to-female connectors but also female-to-male, which in our case would perfectly serve the role of relocating our GPIO port.

After a little trip on the web I found a set of Kuman Ribbon GPIO Cables that would do the job.

Now that the extension is found, remains one more question : how to expose the TV-Hat safely outside ? It didn’t took me long until I found the perfect match.

As I had a spare Premium Raspberry Pi Zero Case lying around, I could use it to hold and protect the TV-Hat, offering GPIO accesses on both top & bottom sides at the same time.

Also, luckily enough, its side where would normally fit the SDCard part of a PiZero, would be properly positioned to give access to the aerial adapter, after some cuts made in the internal casing.

The removable cap would also allow me to protect the hat-based connector for the aerial adapter, if not being used.

As you can see, the top GPIO access port was also put to use. A Pimoroni Blinkt! came along to provide in the future color-based information status and a Button SHIM as well to give first-hand control over the setup.

Everything was then ready for the the first trial.

Time to setup the software bits

The advantage of using a hard-drive based setup, was that I could hold both the Raspbian Operating System and the video recordings on the same unit. No fear of running out of space in that kind of setup.

The distribution provided by WD for its disk make it quite simple to select the hard-drive as a target. The only SD Card requirement is small, such as a 4Gb one or even smaller, to just bounce onto the hard-drive.

After a traditional Raspbian setup (activate ssh, sudo apt-get update & upgrade), it’s time to install the necessary libraries and software.

First, I installed Pimoroni’s one line installers for the blinkt! and button SHIM:

curl https://get.pimoroni.com/buttonshim | bash
curl https://get.pimoroni.com/blinkt | bash

Then I easily installed the TVHeadEnd software package as explained perfectly in The PiHut’s Instructions. It was a piece of cake to have the system running in no time.

Concerning TVHeadEnd, I can only encourage you to get and purchase the full version of TVHClient as it allows you to fully control from your Android device, the TVHeadEnd system. Plus, you can also use it to broadcast, through a ChromeCast, any recording you make which I find great. Its interface is very natural and presents no problem to schedule you first recordings.

Ready to Go for the first test

It was my lucky night when I did my first recording : the great Apollo 13 was on that evening and offered me a nice spectacle. Crystal clear image, easy recording options, the first use of the TV-Hat was a success.

I had kept the Raspbian GUI at first for easier control, but then decided to switch it off to keep the command-line only interface, in order to keep as much processing power for recording and streaming from the set.

As you can see, running the Blinkt! add-on would defenetly put some more colors to the flashy white light emitted by the WD Hard-Drive.

Who knows, may be it can transform in the future into a full ambient-light system ? … I must keep that in mind for another project.

It’s Pi-ty Time !!

Steady, Steady!

But as you can see, this new “extension” to the enclosure was not presenting the best signs of stability.

As the only thing holding the TV-Hat, Blinkt! and Button SHIM is the male connector of the GPIO cable, this definitely needs some reinforcement.

It was then time to get busy with the 3D printer in order to design a little expansion for the enclosure to keep everybody all together.

The TV-Hat “Holder” extension

This little design had to be able to clip easily on the top of the container, firmly enough to keep the male header of the cable in place and to fit properly in the “Raspberry Pi” spirit.

“Keep it all together”

It took me two attempts to finally come up with the proper design and positioning that would be satisfactory.

Bonus Round : One button shutdown & status light

As I originally intended to control the box without need of any ssh command to turn it off, I started to build the first controls around the Button SHIM. Therefore, I used the “E” button to trigger the shutdown of the box as well as used the SHIM’s single LED for status control.

I used a simple python service module to do so, in a “pitv.service” file :

[Unit]
Description=PiTV service
After=network.target
[Service]
ExecStart=/usr/bin/python3 -u /home/pi/scripts/pitv.py
WorkingDirectory=/home/pi/scripts
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi
[Install]
WantedBy=multi-user.target

The last bit was to design the Python code to add Green light status at startup, Red when manually set to shutdown, and Off when being turned off. The “pitv.py” file’s contract was then defined :

#!/usr/bin/env python
import signal
import subprocess
import buttonshim
terminated=False
@buttonshim.on_press(buttonshim.BUTTON_E)
def button_e(button, pressed):
  global terminated
  if not terminated:
    terminated=True
    buttonshim.set_pixel(0xff, 0x00, 0x00)
    subprocess.check_call(['sudo', 'poweroff'])
def signal_handler(signum, frame):
  print('GOT '+str(signum))
  switcher = {
    signal.SIGTERM: handle_sigterm
  }
  # Get the function from switcher dictionary
  func = switcher.get(signum)
  if func:
    func()
def handle_sigterm():
  print('Handled SIGTERM')
  buttonshim.set_pixel(0x00, 0x00, 0x00)
def main():
  buttonshim.set_pixel(0x00, 0xff, 0x00)
  try:
    print('STARTED')
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGHUP, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)
    signal.pause()
  except KeyboardInterrupt:
    pass
  finally:
    print('DONE')

if __name__== "__main__":
  main()

Conclusion

I had great fun building this project and now must dive into the TVHeadEnd API and controls to be able to put into motion all the lights available ;)

Links

Thingiverse File for External DVB Tunner Support for WD Pi-Drive