Điều khiển RPI từ xa

Để gọi chạy từ xa lệnh Linux trên RPI, chúng ta phải bằng cách nào đó gởi đến RPI một từ khóa qui ước. Có thể gởi từ khóa này qua email hay tin nhắn SMS. Bởi vì từ khóa hay nhiều từ khóa có thể nẳm lẫn trong phần text khác nên cần dùng Regular Expression để nhận dạng. Chúng ta cần phải dùng một ngôn ngữ hỗ trợ tương đối đầy đủ Regular Expression, thí dụ Bash, Perl, Python, PHP... Tuy nhiên, các ngôn ngữ lập trình có thể hiểu biểu thức Regular Expression hơi khác nhau, cả về hình thức lẫn cách làm việc; do đó kết quả đôi khi cũng khác nhau.

Thí dụ sau đây trong ngôn ngữ Bash kiểm tra chuỗi test có giống một dòng crontab hay không?

if [[ "$test" =~ [-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]].+ ]]; then
   echo 'YES'
else
   echo 'NO'
fi

Chuỗi regular expression trên viết lại trong ngôn ngữ PHP

if (preg_match('[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s.+', $test))
   echo 'YES';
else
   echo 'NO';

+ Giả sử chúng ta cần điều khiển các dịch vu camera|dlna|nas, bật/tắt qua từ khóa on|off

const service='camera|dlna|nas';
const action='on|off';

+ Biểu thức Regular Expression như sau

$keyword='/\b(' . self::service . ') +(' . self::action . ')\b/i';

+ Nội dung lệnh điều khiển nhận qua tin nhắn hay email là $content, tương tự như turn camera on, dlna off and nas on. Dùng Regular Expression để dò tìm từ khóa

if (preg_match_all($keyword, $content, $m)){
    $service = array_map('strtolower',$m[1]);
    $onoff = array_map('strtolower',$m[2]);
    for ($i=0; $i<count($service); $i++){
           exec("sudo /path/to/php-exec {$service[$i]} {$onoff[$i]}");
    }
}

+ Từ khóa điều khiển được phân tích và lưu trong 2 mảng

$service = array ('camera', 'dlna', 'nas')
$onoff = array ('on', 'off', 'on')

php-exec là tập tin Bash dùng để start/stop các dịch vụ trên Linux (xem bài trước), chạy với quyền root, nội dung tương tự như sau

#!/bin/bash
[ $# -ne 2 ] && exit 1
service=$1
onoff=$2
case $service in
   camera|motion)
      service='camera'
      if [ "$onoff" = 'on' ]; then
         [ "$(pidof motion)" ] || /usr/bin/motion
      else
         [ "$(pidof motion)" ] && /usr/bin/killall motion
      fi
      ;;
   nas|samba)
      service='nas'
      if [ "$onoff" = 'on' ]; then
         [ "$(pidof smbd)" ] || service samba start
      else
         [ "$(pidof smbd)" ] && service samba stop
      fi
      ;;
   dlna|media)
      service='dlna'
      if [ "$onoff" = 'on' ]; then
         [ "$(pidof minidlna)" ] || service minidlna start
      else
         [ "$(pidof minidlna)" ] && service minidlna stop
      fi
      ;;
   *)
      exit 1
      ;;
esac
#tạo file đánh dấu dịch vụ đang chạy
if [ "$onoff" = 'on' ]; then
   echo 1 > "/var/run/$service.rctrl"
else
   rm -f  "/var/run/$service.rctrl"
fi
exit 0

Chú thích

  • Nếu dùng email để gởi từ khóa, dùng mailgun.com để không phải định kỳ kiểm tra email mới (Xem Bài 17). Ngay khi có email đến, mailgun sẽ gọi chạy ứng dụng dò tìm từ khóa.
  • Để bảo mật, ứng dụng chỉ xử lý lệnh từ các user, email, số điện thoại đã đăng ký trước.
  • Có thể thiết kế một trang web có sẵn các từ khóa qui ước để gọi chạy lệnh Linux. Với cách này không cần dùng Regular Expression, nhưng hoạt động không linh hoạt như cách đã bàn bên trên.
  • Có thể ssh đến RPI từ xa nếu mở port 22 và có ddns

Leave a Comment

Filed under Software

Leave a Reply