舊手機威力之看門狗

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

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

解決方案前端

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

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

如圖所示,若是關門了,經過照片能看出是否關門了,這裏拍攝的是打了小鎖的狀況。git

實施方案github

硬件:web

  • 時刻聯網的舊手機

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

軟件:編程

  • 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

相關文章
相關標籤/搜索