Senior citizen-friendly video telephony system with a Raspberry Pi

Push of a Button

© Lead Image © Darek Chramienko, 123RF.com

© Lead Image © Darek Chramienko, 123RF.com

Author(s):

A video telephony system with huge user benefits does not have to be complex. This project starts a phone call with just a single button press and switches channels automatically on a TV.

The coronavirus pandemic has the world in its grasp. With social distancing and family dispersion, many people are not able to see their grandchildren. Even a cellphone is too complicated for some senior citizens, and they may not want to have anything to do with PCs. One alternative could be an Internet-enabled baby monitor with a return channel, but it won't have video. Besides, grandma and grandpa don't want to be monitored, and you don't want the baby monitor to alert you every time your grandparents walk past the device.

With no simple video phone to be found thus far, the question is whether the Raspberry Pi comes to the rescue and whether it can be built without any advanced Raspberry Pi knowledge. In this article, I look at a video telephony solution based on the Jitsi [1] open source video conferencing solution that is useful for even the least computer savvy seniors (see the "Jitsi and WebRTC" box). One button turns everything on and just as easily turns everything off again. Ultimately, the Raspberry Pi needs to be able to do three things: switch the TV to HDMI, send email, and, of course, start the video call.

Jitsi and WebRTC

Today, many multimedia applications such as audio or video calls no longer require separate programs such as Skype. The free WebRTC [2] standard enables modern web browsers to send voice, video, and data directly from user to user – and without a central server instance. Jitsi is based on WebRTC and, as an open source solution, does not even require authentication. It is enough to open a Jitsi meeting on a website [3] and send an invitation to the conversation in the form of a URL over email or chat to the desired call partners. This straightforward approach makes Jitsi Meet an ideal candidate for a senior-friendly video chat solution.

Hardware and Preparations

The setup of the automated video conferencing system is based on a Raspberry Pi 3B+ with a case and a power supply, on which the latest version of the Raspberry Pi OS "Buster" is installed and Internet access is configured. To be able to control a TV by CEC (Consumer Electronics Control), you also need an HDMI cable that meets at least HDMI standard 1.3 (high speed). Also pay attention to the quality of the power supply. Because the webcam is powered by the Raspberry Pi over USB, the power supply needs to output 2.5A or more. Only testing can determine whether the power source will do, because even if the label on the adapter claims the right kind of performance, it might not necessarily achieve it in practice.

Ultimately, the shopping list includes a simple push button with two matching connecting cables that will later serve as an on/off switch. For the button, I drilled a hole into the case. If your expectations for the webcam are not too high, all of the components together will set you back something south of $100. The Raspberry Pi 3 would be overtaxed with very high resolutions, anyway, so a very simple webcam is absolutely fine (Figure 1). In the test, I worked with a no-name camera from my lab treasure trove. Although it has a microphone, it does not work as a USB audio device, so I needed an additional USB sound card with analog audio input. Alternatively, I tested a more modern webcam from Logitech.

Figure 1: The complete hardware (here with an older webcam and separate USB sound card).

After setting up and configuring the video chat solution, the Pi does not need any input devices. For the initial setup, however, connecting an external keyboard and mouse makes work easier. You should also enable SSH access with the raspi-config configuration tool. In this way you can connect to the system over the network and, for example, install updates, even when the keyboard has been removed from the Raspberry Pi.

On the software side, the Chromium browser and the important x11-xserver-utils component are usually already included by default in the current Raspberry Pi OS. However, if you are building the system on an older Raspbian version, you might still need to install the chromium-browser and x11-xserver-utils packages:

$ sudo apt update && sudo apt full-upgrade
$ sudo apt install chromium-browser x11-xserver-utils

The first line updates the system before you start the installation.

Dispatching Email

For the system to be able to send email on its own, you don't necessarily have to set up a complex mail server (or more precisely, MTA, Mail Transfer Agent) such as Sendmail or Postfix – that would be over the top. It is easier to integrate an existing email account with a web mailer (e.g., AOL Mail, Gmail, Outlook.com, Yahoo! Mail). The email client's task is handled by the msmtp [4] command-line program. You can import all the necessary components with:

$ sudo apt install rdate msmtp msmtp-mta mailutils

For the configuration you then have to create three text files. In the following example, I will be using the services of the German portal Web.de; however, you can use any other email provider that operates an SMTP server. The server addresses, ports, and access data are usually explained by the services in the depths of their documentation. To set up the email tool for your web mailer, open the text editor with

sudo nano /etc/msmtprc

copy the content from Listing 1, and paste it into this file.

Listing 1

/etc/msmtprc

# default values
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
# web.de
account <john.doe>@web.de
host smtp.web.de
port 587
from <john.doe>@web.de
user <john.doe>@web.de
password <SecretPassword>
account default: <john.doe>@web.de
aliases /etc/aliases

Of course, you do need to adjust the email address and password to match the service you use. Save the change by pressing Ctrl+O and Enter and return to the command line by pressing Ctrl+X. Remember this procedure: In the following instructions you will need to edit and save more text files in Nano. Note that the password (here, <SecretPassword>) is open and unencrypted in this file. To prevent every user on the system from gaining access to the credentials, use the

sudo chmod 600 /etc/msmtprc

command to change the file permissions.

In the next step, assign the sender, in this case the root user, the email account just configured as the sender. To do this, create the /etc/aliases file in Nano the same way as before and enter the customized contents:

root: <john.doe>@web.de
default: <john.doe>@web.de

Finally, to make sure that the system uses msmtp as the email program, the line

set sendmail="/usr/bin/msmtp -t"

in the /etc/mail.rc file defines it as the alternative to sendmail.

TV Remote Control

To avoid your grandparents having to fiddle with the remote control, you now want the system to turn on the TV and switch to the correct HDMI input automatically – and switch back to the normal cable TV tuner after hanging up. For this, the Raspberry Pi and TV communicate with each other by CEC on the HDMI cable. You can install the necessary software from the cec-utils package. Then scan for CEC-capable devices (Listing 2).

Listing 2

TV Remote Control by CEC

$ sudo apt install cec-utils
$ echo 'scan' | cec-client -s -d 1
opening a connection to the CEC adapter...
requesting CEC bus information ...
CEC bus information
===================
device #0: TV
address:       0.0.0.0
active source: no
vendor:        LG
osd string:    TV
CEC version:   1.3a
power status:  unknown
language:      eng
[...]

Typically, the TV advertises itself as device #0 and the Raspberry Pi as device #1. If only the Raspberry Pi appears in the list (vendor: "Pulse Eight"), CEC is probably not enabled on the TV.

Depending on the manufacturer, the name for the CEC technology differs: LG refers to it as SimpLink, Sony uses the term BRAVIA Sync, and Samsung says Anynet+. An overview of common manufacturer designations can be found on Wikipedia [5].

If it still doesn't work, you need to take a closer look at the HDMI cable. If it is not a high-speed cable, the communication channel to the TV is usually missing.

Autostart All Services

Processes and programs can be started automatically in different ways on the Raspberry Pi. In this example, I will be using a desktop file that starts a number of processes in parallel in the background. The advantage of this procedure is that the LXDE interface starts up completely in the background, and you end up in the graphical user interface after exiting the web browser by pressing the Ctrl+F4 hotkey.

For this example, enter

sudo nano /etc/xdg/autostart/usr_autostart.desktop

to create the autostart file and add the following content:

[Desktop Entry]
Type=Application
Name=usr_autostart.sh
Comment=user defined autostart script
NoDisplay=false
Exec=/bin/bash /home/pi/usr_autostart.sh

The system reads the usr_autostart.desktop file when booting the graphical interface and then executes the command entered in the Exec line. In this case, the system loads the script /home/pi/usr_autostart.sh, which has the startup commands.

Again you have to create this file manually by typing

nano /home/pi/usr_autostart.sh

and adding the content shown in Listing 3. To allow the system to execute the file, adjust the permissions after saving with

chmod +x /home/pi/usr_autostart.sh

Listing 3

usr_autostart.sh

01 #!/bin/bash
02 ### Turn off the mouse pointer after 5 seconds of inactivity.
03 unclutter -idle 5
04 ### Turn off the screen saver and power saving functions.
05 xset -dpms
06 xset s off
07 xset s noblank
08 ### Turn on the TV and switch to HDMI.
09 echo 'on 0' | cec-client -s -d 1
10 echo 'as' | cec-client -s -d 1
11 ### Update date and time from Fritzbox for email.
12 sudo rdate -4nu -s <192.168.178.1>
13 ### Send email with link that Jitsi has started.
14 sudo echo 'https://meet.jit.si/<MeetID>#config.prejoinPageEnabled=false&config.disableAP=true&config.noisyMicDetection=false&config.video.height.ideal=240&config.video.width.ideal=360' | mail -s 'Jitsi Meeting ID is online' <the.grandson@example.com>
15 ### Start Jitsi meeting in Chromium.
16 chromium-browser --noerrdialogs --disable-crash-reporter --kiosk https://meet.jit.si/<MeetID>#config.prejoinPageEnabled=false&config.disableAP=true&config.noisyMicDetection=false&config.video.height.ideal=240&config.video.width.ideal=360
17 exit

The usr_autostart.sh file outsources four tasks:

  • Turning off the mouse pointer and the screen saver (lines 2-7).
  • Turning on the connected TV and switching to the HDMI input (lines 8-10).
  • Sending a notification to a specified email address (lines 11-14).
  • Starting the Jitsi meeting in the Chromium browser (line 16).

The xset command from the x11-xserver-utils package, which can be used to turn off the screen saver, among other things, is part of the default installation. To turn off the mouse pointer, install the unclutter package with:

sudo apt install unclutter

The TV device is controlled by the previously installed cec-client. With a pipe (|), you can forward the command output with an echo to the client. For example,

echo 'on 0'

wakes up the device with device number 0 from standby, and

echo 'as'
echo 'is'

switches the HDMI input of the Raspberry Pi to active and inactive.

You can set the <MeetID> in lines 14 and 16 freely. However, when choosing the ID, make sure that strangers do not hijack the video call. A random alphanumeric string such as that output by the command

xxd -l16 -ps /dev/urandom

would be a good choice. Additionally, you have to adjust the IP address of the wireless router in line 12; the same applies to the email address of the recipient of the notification in line 14.

The call to Jitsi in the web browser in line 16 passes a set of parameters:

  • config.prejoinPageEnabled=false suppresses a prompt for which username to use when joining the meeting. Without a mouse and keyboard, this would be impossible to answer.
  • config.disableAP=true disables audio processing, mainly to reduce the load on the Raspberry Pi CPU.
  • config.noisyMicDetection=false prevents a warning message from appearing as soon as the microphone signal becomes noisy.
  • config.video.height.ideal=240=360 reduces the video resolution to save the Raspberry Pi's processor.

You will often read on Internet forums that exit at the end of a script that runs all the way through is not good style, but when I tried a script without exit, Chromium failed to start; at the end of the day, the instruction does not do any harm.

Keystroke Shutdown

Now you have established a connection, but a routine is still missing that shuts down the system properly. The grandparents should not have to adjust anything on the Raspberry Pi or the TV.

For this purpose, I drilled a hole in the case for a switch that sits between the processor and the USB ports above the board; some space is available there for the connection cables. After I installed a suitable push button in the housing, I connected it with one cable each to GPIO pins 5 and 9 (GND) to close a circuit when the button is pressed (Figure 2). Connected to pin 5, the button also wakes the Raspberry Pi from sleep mode if the small-board computer is connected to a power supply (Figure 3). This function is integrated at the factory and requires no further configuration [6].

Figure 2: The push button is installed centrally on the top of the housing.
Figure 3: Schematic diagram of the circuit (created with Fritzing).

If the Raspberry Pi is running, the button will initiate a shutdown process that switches the HDMI input of the TV back to inactive, which, in turn, usually causes the TV to switch to the last selected channel. Furthermore, you want the Raspberry Pi to shut down the operating system gracefully, which includes exiting Chromium and thus the video conference.

To do this, the system needs to monitor GPIO pin 5 continuously, as performed by the/home/pi/shutdown.py script (Listing 4). This script needs to be started before the graphical user interface in the existing /etc/rc.local file with the shutdown entry,

#!/bin/sh -e
[...]
python /home/pi/shutdown.py &
exit 0

Listing 4

/home/pi/shutdown.py

01 # Shutdown script
02 # Waits for LOW at pin 5
03
04 import RPi.GPIO as GPIO
05 import os
06
07 GPIO.setmode(GPIO.BOARD)
08 # GPIO pin 5 as input with signal HIGH
09 GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
10
11 try:
12   while True:
13     # Waits for the pin to be connected to GND
14     GPIO.wait_for_edge(5, GPIO.FALLING)
15     # Raspberry Pi signal is turned off at the TV
16     os.system("echo 'is' | cec-client -s -d 1")
17     # os.system("echo 'tx 10:9D:10:00' | cec-client -s -d 1")
18     # Proper shutdown, also of Chromium
19     os.system("shutdown -h now")
20
21 except:
22   GPIO.cleanup()

which should appear in the penultimate line, before the final exit 0, as shown. Be sure to include the & at the end of the Python program call; otherwise, the system will wait for the script to finish, which would cause the system to freeze.

Finally, you need to make the Python script executable by typing:

sudo chmod +x /home/pi/shutdown.py

You should also take a look at lines 16 and 17 of Listing 4. According to the specification, the CEC call echo 'is' switches the HDMI signal to inactive. In combination with my Sony Bravia TV, however, this command did not do what the doctor ordered. The TV continued to display the picture of the Raspberry Pi system fed in over HDMI. Fortunately, deregistering the signal at the TV with a CEC frame injection by calling echo 'tx 10:9D:10:00' worked.

If you experience issues, try one of the two calls by removing the hash symbol # in one line and adding it to the other line. Unfortunately, every manufacturer does its own thing when it comes to CEC. Often, CEC only really works reliably with newer TV sets.

Input and Output Devices

To guarantee that the system always outputs audio through the TV and records audio from the microphone built into the webcam, you need to enter the audio devices permanently on the system. To do this, display the input and output devices detected by Raspberry Pi OS with aplay -l and arecord -l (Listing 5).

Listing 5

Detected Devices

$ aplay -l
   List of hardware devices (PLAYBACK)
Card 0: b1 [bcm2835 HDMI 1], Device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1].
  Sub devices: 4/4
[...]
Card 1: Headphones [bcm2835 Headphones], Device 0: bcm2835 Headphones [bcm2835 Headphones].
  Sub devices: 4/4
[...]
$ arecord -l
   List of hardware devices (CAPTURE)
Card 2: C920 [HD Pro Webcam C920], Device 0: USB Audio [USB Audio].
  Sub devices: 1/1
  Sub-device #0: subdevice #0

The important parts of this output are the device names that follow the card numbers; in this example, b1 is the HDMI output, Headphones the analog headphone jack on the Raspberry Pi, and C920 the Logitech webcam used in the setup.

Now create the appropriate settings file by typing

sudo nano /etc/asound.conf

and pasting the content from Listing 6. Usually, you will only need to adjust the device name of the webcam microphone in line 9. After a restart, the correct devices should now be selected automatically.

Listing 6

/etc/asound.conf

01 pcm.!default {
02   type asym
03   capture.pcm "mic
04   playback.pcm "speaker
05 }
06 pcm.mic {
07   type plug
08   slave {
09     pcm "hw:<C920>"
10   }
11 }
12 pcm.speaker {
13   type plug
14   slave {
15     pcm "hw:b1"
16   }
17 }

The WebRTC test page [7] should then report no errors, and the audio and video test for WebRTC [8] should output image and sound from the webcam (Figure 4).

Figure 4: The WebRTC test indicates that everything is OK: To be on the safe side, use the volume slider context menu to check that the system is using the correct input and output devices.

Picking Up a Phone Call

The receiving side does not need to go through as much trouble because I assume that the children and grandchildren have a PC or smartphone. To receive the call from grandma and grandpa, all they have to do is open the link from the email into a web browser, and the grandparents appear on the screen.

Theory and Practice

During the first field test of the full setup, massive interference in the microphone signal occurred in Jitsi. In a direct test of the microphone and sound card (on the Raspberry Pi and a Windows PC), the errors could not be reproduced, so the hardware is obviously not responsible.

The explanation was too weak a power supply, which was overtaxed by supplying power to the Raspberry Pi, sound card, and webcam. A better power supply quickly provided a remedy; alternatively, the use of a USB hub with its own power supply is also an option.

It turns out that the third generation of the Raspberry Pi is overtaxed by high-definition video telephony. Transferring the picture and sound without interruption proved to be a difficult task. On the one hand, the latency caused a noticeable delay during the call. On the other, the echo and acoustic feedback effects disturbed the sound because I couldn't shield the webcam's microphone against the TV's speakers.

If you don't want to upgrade to a far more powerful Raspberry Pi 4, you can mitigate both issues by reducing the CPU load during the video call – which is why Jitsi is called with the parameters shown in the scripts. The picture and sound quality are not perfect, but good enough.

Sources of Error

In the initial phase with the video telephony system, it quite often happened that my grandparents accidentally switched their Sony TV to standby with the remote control while the Raspberry Pi was still running. After that, setting the HDMI input to inactive did not work as desired because the TV did not know what signal source it had been displaying before the Raspberry Pi. The Raspberry Pi's HDMI input remained the last activated input source, and my grandparents needed help because they did not know how to switch to the TV function on the TV. Disaster: the TV stayed black even after it was switched back on.

The attempt to switch the signal source actively to a TV channel by CEC before shutdown did not succeed. In the worst case, the TV still showed a black screen after switching on, but at least it switched back to a TV channel after starting and shutting down video telephony. Some CEC functions are supposed to control the TV's digital tuner remotely; however, in the setup used here, the call from the Raspberry Pi reported that the command was not recognized.

The Sony's remote control has a button for switching between analog and digital, which can also switch the signal input back to the TV. Fortunately, I could communicate this information by telephone. Happily, my grandparents only make this mistake once in a while and should improve their skills over time. To eliminate this source of error completely, the system would have to be given its own TV set. Smaller devices are available second-hand for just a few dollars.

Conclusions

The term "plug and play" seems a bit like overkill for this video telephony system, but once network access is configured, the Jitsi meeting has been given a name in the code, and the email account is set up, all you really need to do is plug the Raspberry Pi into a suitable CEC-enabled TV.

To make a call, the user then just presses a button and waits for the other party to join the Jitsi session. The first time you do this, you should go through the steps with the mouse and keyboard connected to disable one-off notifications, check the CEC response, and enable the microphone and camera. After that, grandma and grandpa should be able to manage the system.

The original source for the project from Instructables [9] is a few years old and ultimately only provided some inspiration and a starting point. The video telephony system described here configures the audio devices, controls the TV set, and automates everything with a single button.

If I had found a solution to purchase, then this project would never have taken off. But for a newcomer, the potential learning effect is massive, especially if you do not simply copy the code, but also look up what it actually does. Most importantly, it produces results that have a tremendous utility value.

The Author

Mathematician Manfred Puckhaber has a wide range of interests and describes himself as a "results-oriented do-it-yourselfer," who only learned to appreciate the Raspberry Pi in the course of this project.