舊手機威力之看門狗

不知道大家是否有關門後又回到門口檢查門是否關了的經歷,反正我有,作爲一個懶人應該採取一些措施,在不往回跑的前提下檢查門是否關了。

幾乎沒有忘記關過門,但是強迫症逼死人:(

解決方案

遠程控制聯網手機在房內對門口拍照,然後查看圖片檢查是否關門. 遠程方面使用web方式.

這裏放一張截圖:
舊手機威力之看門狗

如圖所示,如果關門了,通過照片能看出是否關門了,這裏拍攝的是打了小鎖的情況。

實施方案

硬件:

  • 時刻聯網的舊手機

    這裏使用的紅米note7 pro做的測試, 舊手機有點問題.

軟件:

  • termux 0.69
  • termux-api 0.32
  • juiceSSH(可選)
  • python3
  • frp(選擇自己喜歡的內網穿透方式)

環境準備

主要是手機APP安裝以及APP裏面Linux環境軟件的安裝

手機APP

手機安裝termux, termux-api, juiceSSH

通過你中意的應用市場找到這兩個app然後安裝

建議通過Google商店安裝, 不過可能有難度,需要自行研究

安裝好之後可以通過自帶的窗口或者通過JuiceSSH連接,因爲JuiceSSH對於命令輸入更友好

關於JuiceSSH或者電腦連接手機的Termux可以參考: 一箇舊手機的威力

Termux Linux環境

Linux包以及Python包

安裝termux-api用於訪問手機相機

pkg install termux-api

一定要既安裝手機APP的Termux-API, 也要通過上面命令安裝termux-api

通過這個包我們可以獲得一堆訪問手機意見或者軟件的訪問API, 比如相機,短信,電話,震動之類的API.

可通過以下命令調用手機相機拍照

# 查看幫助
➜  ~ termux-camera-photo -h    
Usage: termux-camera-photo [-c camera-id] output-file
Take a photo and save it to a file in JPEG format.
  -c camera-id  ID of the camera to use (see termux-camera-info), default: 0

# 通過相機id爲1的相機拍照,並保存相片到本地1.jpeg
termux-camera-photo -c 1 1.jpeg

至於你的哪個相機是前置哪個是後置,或者某個後置(後置可能有多個), 需要自己測試。

但是上面的照片是放在APK的存儲空間裏面,所以手機相冊看不到,所以需要通過其他API將圖片放到手機的本地存儲。

執行以下命令後,會在加目錄生成一個storage目錄,通過這個目錄我們可以在termux內訪問手機的本地存儲

# 手機應該會詢問該APP可否訪問手機存儲
termux-setup-storage

然後我們就可以將將拍攝的圖片移到外面,然後就可以通過相冊或者文件管理器打開

cp 1.jpeg storage/downloads

注: 在執行相關命令的時候會彈出權限是否允許,需要手動點擊允許, 不允許的話自然這些API或者說命令都沒法用了.

Termux-API參考鏈接: Termux-API

Python相關依賴

選擇你自己喜歡的編程語言或者web框架都可以了,這裏選擇Python, flask實現web遠程控制。

# 安裝Python
pkg install python

# 安裝flask pillow
pip install flask pillow

安裝pillow是爲了壓縮圖片。

如果安裝sanic, pillow失敗,可以考慮安裝以下依賴(我安裝了很多的其他庫,所以確定哪個是一定必要的)

apt install python python-dev clang fftw libzmq libzmq-dev freetype freetype-dev libpng libpng-dev pkg-config zlib zlib-dev libiconv libiconv-dev curl

內網穿透也參考這篇文章: 一箇舊手機的威力

至此我們完成了所有的準備工作。

web遠程控制

效果如下
舊手機威力之看門狗

由於我暫時沒想好一個好的放置位置(跟房間佈局有關),所以暫時還沒有實際應用,所以照片拍攝的照片是手持手機,然後遠程控制拍攝。

代碼實現

純演示項目,如果覺得有意思自己完善吧。

爲了儘可能的少代碼,前端方面沒使用任何第三方庫。

目錄結構

➜  ~ tree watchdog                
watchdog
├── app.py
├── static
│   ├── 2019-05-18-18-54-00.jpeg
│   └── latest.jpeg
└── templates
    └── index.html

2 directories, 4 files

代碼app.py

from flask import Flask
import subprocess as sp
from datetime import datetime
from PIL import Image
from os import path
from flask import render_template
app = Flask(__name__)

@app.route("/")
def index():
    # 爲了不緩存圖片
    now = datetime.now()
    timestamp = now.timestamp()
    return render_template('index.html', timestamp=timestamp)

@app.route("/watch")
def watch():
    cwd = path.dirname(path.abspath("__file__"))
    static_dir = path.join(cwd, "static")
    now = datetime.now()
    date_str = now.strftime("%Y-%m-%d-%H-%M-%S")
    # 拍攝的照片保存位置
    img_path = path.join(static_dir, "{}.jpeg".format(date_str))
    print(img_path)
    # 拼湊出latest.png文件路徑
    latest_img_path = path.join(static_dir, "latest.jpeg")
    print(latest_img_path)
    cmd = "termux-camera-photo -c 0 {}".format(img_path)
    retcode = sp.call(cmd, shell=True)

    if retcode != 0:
        return "failed"

    img = Image.open(img_path)
    # 根據實際圖片壓縮,自己測試
    new_img = img.resize((int(img.size[0] * 0.4), int(img.size[1] * 0.4)))
    try:
        new_img.save(latest_img_path)
    except Exception as e:
        print(e)
        return "failed"
    return "ok"

if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True)

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Watch Dog</title>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="0">
    <style>
        .container {
            text-align: center;
        }

        img {
            width: 80%;
        }
        button{
            padding: 10px 40px;
            background: #09F;
            color: #FFF;
            text-decoration: none;
        }
    </style>

    <script type="text/javascript">
        function watch() {
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/watch", true)
            xhttp.onloadend = e => {
                var resp = xhttp.responseText
                alert(resp)
                if (resp == "ok") {
                    // 刷新頁面
                    window.location.reload()
                }
            };  
            xhttp.send()
        }

    </script>
</head>
<body>
<div class="container">
    <!-- 加個時間戳爲了強制更新圖片 -->
    <img src="/static/latest.jpeg?{{timestamp}}" alt="">
    <br>
    <button onclick="watch()">關門了嗎?</button>
</div>

</body>
</html>

在windows上安裝一些需要編譯的python庫實在是件痛苦的事情,因爲需要Microsoft Visual C++ 14.0, 而爲了裝這個又得需要裝visual studio.

總結

總的來說流程如下

  1. 安裝必要的軟件
  2. 找一個合適的地方放置手機
  3. 編寫自己喜歡的遠程控制方式
  4. 內網穿透或者其他方式連接控制端

如果你喜歡的話也可以通過寫一個APP的方式實現。

代碼鏈接: watchdog

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章