見出し画像

Raspberry Pi Zero Wを使って自宅のWi-Fiに接続している機器をスキャン。(後編)

前回、無事にラズパイにsshで接続ができて、ここから実際にプログラムを移植していきます。

ローカルで作ったプログラムはnode.jsで用意したので、ラズパイにもnode.jsをインストールするところからスタート。

他力本願

で、もらった手順に従って実行すると「Illegal instruction」と返ってくる。Illegal instructionエラーは、Node.jsのビルドがRaspberry Piの特定のアーキテクチャに対応していない場合に発生することがあるとのこと。

Node Version Manager (nvm)を使用したインストール方法を提案されたのでやってみるもこれも空振り・・・5時間実行した末の失敗・・・つらい・・・(僕は寝てただけだけど)

nodeのバージョンを変えてみるもこれも効かない。かなり粘るも突破口見つからず・・・他の言語のおすすめを聞くと、Pythonが良いとのことなので、

おすすめで!

や〜初学者でもさらっと別言語に切り替える選択肢が持てるのは素晴らしいことですね。。。昔だったらここからまた3ヶ月とか余裕でかかってしまうよ・・・

で、気を取り直してラズパイにPythonを入れようとすると、仮想環境で実効せいとのエラーが出る。

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    For more information visit http://rptl.io/venv

ということで、仮想環境を作成。

# 仮想環境の作成
python3 -m venv myenv

# 仮想環境の有効化
source myenv/bin/activate

# パッケージのインストール
pip install scapy requests

# スクリプトの実行
python network_check.py

最終版のコードはこちら。

from scapy.all import ARP, Ether, srp
import requests
import time

# 監視するMACアドレスのリスト(すべて小文字で記載)
target_mac_addresses = [
    'ここにMACアドレスを記載',
    'ここにMACアドレスを記載',
    'ここにMACアドレスを記載' 
]

# Webhook URL
webhook_url = 'ここにIFTTTでつくったWebhookのURLを記載'

# スキャンするネットワーク範囲
network_range = '自宅のWi-Fiネットワークを記載'

# 状態管理変数
consecutive_misses = 0

def scan_network():
    arp = ARP(pdst=network_range)
    ether = Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether/arp

    result = srp(packet, timeout=3, verbose=0)[0]

    devices = []
    for sent, received in result:
        devices.append({'ip': received.psrc, 'mac': received.hwsrc.lower()})
    return devices

def trigger_webhook():
    try:
        response = requests.post(webhook_url)
        response.raise_for_status()
        print('Webhook triggered:', response.text)
    except requests.exceptions.RequestException as err:
        print('Error triggering webhook:', err)

def check_network():
    global consecutive_misses
    print('ネットワークスキャン中...')
    network_entries = scan_network()
    print('ネットワークスキャン結果:')
    for entry in network_entries:
        print(f"IPアドレス: {entry['ip']}, MACアドレス: {entry['mac']}")

    any_device_found = any(entry['mac'] in target_mac_addresses for entry in network_entries)

    if not any_device_found:
        consecutive_misses += 1
        print(f"すべてのデバイスが見つかりませんでした。連続回数: {consecutive_misses}")
        if consecutive_misses >= 2:
            print("2回連続でデバイスが見つかりませんでした。Webhookを叩きます。")
            trigger_webhook()
            consecutive_misses = 0
    else:
        print("少なくとも1つのデバイスがネットワークに存在します。")
        consecutive_misses = 0

if __name__ == "__main__":
    while True:
        check_network()
        time.sleep(15 * 60)

これを実行したところ・・・走った!!!!処理が走った!!!

や〜、感動だな〜っと思っていたのですが、、、このあと事故が起きます。。。次回に続く。

ご覧いただきありがとうございます。とても嬉しいです。