5. External Access

So far we have everything we need to perform a successful motion detection, watch the stream online as well as to manipulate with the Raspberry externally. In this part, however, we will do a little bit of cosmetics in order to facillitate working with the camera externally. Until now, in order to activate or deactivate the program, we needed to log in to the Raspberry and invoke the specific command. Now, we will use Python in order to access Motion more easily.

The point is to create two python scripts to act as server and the client, hence making a tiny abstraction layer for to handle the connection. The scripts will talk to each other, in a way that ssh'ing will be avoided. You can think of it as a starting point for expansion, if you'd like to, for example, enable other members of your family to use the system through an application.

In this simple version, we will use the two modules in both scripts:

Let's start with the server part.

The server part

The server.py is obviously going to be deployed on the Raspberry. Its task will be to listen for connection and depending on incoming command from the client, it will start or stop Motion. Before we begin, however, let us use cron scheduler in order to ensure that this script is executed every single time Raspberry reboots.

In Raspberry's terminal execute:

sudo crontab -e

and select your favourite text editor, when prompted to.
Next, add the following line to the file:

@reboot python /home/USER/PATHTOFILE/server.py &

The capital letters should, of course, be adapted to your case and the & sign is used to free the terminal.

Now, the body of the script:

# TCP server example
import socket
import sys
import os

PORT = 8000

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", PORT))
server_socket.listen(5)

print("TCPServer Waiting for client on port " + str(PORT) + ".")

while True:
  client_socket, address = server_socket.accept()
  print("Client connected from " + str(address) + ".")
  while True:
    data = client_socket.recv(2048)
    if (data == 'q' or data == 'Q'):
      client_socket.close()
      print("Client disconnected.")
      break;
    else:
      print("RECIEVED: " + data + ".")
    if data == 'start':
      os.system("sudo motion start")
      client_socket.send("ON")
    if data == 'stop':
      os.system("sudo pkill motion")
      client_socket.send("OFF")
    if data == 'check':
      response = os.popen("pgrep motion").read()
      if response == '':
        print("Camera is INACTIVE.")
        client_socket.send("OFF")
      else:
        print("Camera is ACTIVE.")
        client_socket.send("ON")
      if not(data in ["start", "stop", "check"]):
        client_socket.send("Wrong command!")
        client_socket.close()
        print("Client disconnected.")
        break;

I guess, you can deduct from the code that after the connection is made, the server waits for the client and responds to keywords. The os.system() function is used to manipulate with Motion as if we did it through the terminal and client_socket.send() transfers the commands between the devices.

The client part

The client.py is to be deployed on a PC (or mobile device) that is used to connect to the camera. The body of the file is the following:

import socket
import sys

PORT = 8000

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("www.YOURDOMAIN.net", PORT))
while True:
  data = raw_input("S<-: ")
   (data == 'Q' or data == 'q'):
    print("C->: Program is closing, disconnecting client.")
    client_socket.close()
    sys.exit()
  if (data == 'H' or data == 'h'):
    print("Little help guide:")
    print(" 'q/Q' for quit")
    print(" 'h/H' for help")
    print(" 'start' for activating the camera")
    print(" 'stop' for disactivating it")
    print(" 'check' for checking of the status")
  else:
    client_socket.send(data)
    data = client_socket.recv(2048)
    print("S->: Camera is " + data + ".")

Demonstration of operation

term
Figure 7. Remote access from Ubuntu terminal.

left