12
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🌿 ラズパイを活用した『社内環境(温湿度)見える化システム』をつくる⑧【HPとラズパイのAPI連携(結合編)

Last updated at Posted at 2025-05-27

はじめに

こんにちは、piyovateです🐣✨

いよいよ今回で『社内環境(温湿度)見える化システム』が完成します!!🎉✨

前回の記事で、ホームページ上で温湿度を表示する仕組みを実装しました。今回は、クラウド環境にあるホームページとRaspberry Pi Pico WHをAPI経由で連携し、温湿度データを10分間隔で自動的に取得・表示する方法を具体的に紹介します。


🎯 今回の目標

  • ホームページ(クラウド環境)とPico WHを連携し、10分間隔でリアルタイムデータを取得
  • Pico WHを外部アクセス可能な状態に設定

🌐 Step1:Raspberry Pi Pico WHの外部アクセス設定

ホームページ側からラズパイにアクセスできるよう、以下の手順でPico WHを設定しました。

1. Raspberry Pi Pico WHのMACアドレスを取得

MicroPythonを利用して、Pico WHのMACアドレスを確認します。

import network

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
mac = wlan.config('mac')

print('MACアドレス:', ':'.join(['%02X' % b for b in mac]))

表示されたMACアドレスをメモしてください。

2. ルーターで固定IPを設定

取得したMACアドレスをルーターの設定で固定IPアドレスに設定します。

3. ドメインを設定し外部からアクセス可能に

取得した固定IPに対してドメインを設定し、HTTPで外部からアクセスできるようにします。


⚙️ Step2:ホームページ側でAPI連携設定

クラウド上のホームページからラズパイのAPIデータにアクセスするために、設定ファイルを修正します。

// raspi-config.js
const ENV_CONFIG = {
    apiUrl: 'http://設定したドメイン名/',

    holidays: [
        // 休日設定
        '2025-01-01', '2025-01-13', /* 他の日付 */
    ]
};

🔄 Step3:ホームページ上での自動データ更新(10分間隔)

JavaScriptのsetIntervalを使って10分ごとに自動的に更新します。

// env-status.js
async function updateComfortStatus() {
    try {
        const res = await fetch(ENV_CONFIG.apiUrl);
        const data = await res.json();

        // データ取得・表示処理
    } catch (err) {
        console.error('データ取得エラー:', err);
    }
}

// 初回実行と10分間隔の更新
updateComfortStatus();
setInterval(updateComfortStatus, 600000); // 600,000ミリ秒 = 10分

🛠️ 問題発生しました:Mixed Contentエラー

本番環境にてホームページをHTTPSで公開していたところ、以下の問題が発生しました。

Mixed Contentエラー:HTTPSページからHTTP APIへアクセスがブロックされる

これは、HTTPSページ上でJavaScriptからRaspberry Pi Pico WH が提供するHTTP APIにアクセスした場合、ブラウザがセキュリティ上ブロックすることで発生します。


🔧 対策:proxy.php による中継(プロキシ)を実装

Step1:proxy.php を設置

以下の proxy.php をサーバーに設置し、HTTPS経由で安全にPico WHのHTTP APIへアクセスする中継処理を追加しました。

<?php
if (!isset($_GET['target'])) {
    http_response_code(400);
    echo json_encode(['error' => 'targetパラメータが必要です']);
    exit;
}

$target = $_GET['target'];
$whitelist = [
    'http://(Raspberry Pi Pico WH のAPI URL)',
];

if (!in_array($target, $whitelist)) {
    http_response_code(403);
    echo json_encode(['error' => '許可されていないURLです']);
    exit;
}

$ch = curl_init($target);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
    http_response_code(500);
    echo json_encode(['error' => '接続エラー']);
} else {
    http_response_code($httpCode);
    header('Content-Type: application/json');
    echo $response;
}
curl_close($ch);
?>

Step2:JavaScript設定ファイルを修正

raspi-config.js にて、API呼び出し先を直接のHTTPではなく、proxyを経由するよう変更しました。

const picoWhApiUrl = 'http://(Raspberry Pi Pico WH のAPI URL)';
const proxyUrl = `/proxy.php?target=${encodeURIComponent(picoWhApiUrl)}`;

const ENV_CONFIG = {
    rasPiPico_apiUrl: proxyUrl,
    national_holidays_apiUrl: `https://api.national-holidays.jp/${new Date().getFullYear()}`,
    holidays: [
        '2021-07-21',
        // 他の臨時休業日もここに記載
    ]
};

picoWhApiUrl には Raspberry Pi Pico WH が提供しているHTTP APIのURLを指定しています。


📝 教訓

HTTPSとHTTPが混在する場合は、必ずHTTPSで統一するか、中継用のproxy処理を導入する必要があるということを今回学びました。

同様の構成を検討している方は、初期段階からAPIのHTTPS化、または中継構成の検討をおすすめします。


🚩 完成後の表示確認

ホームページにアクセスし、10分間隔で自動更新されることを確認します。

表示例:

現在のオフィス環境:温度😌 / 湿度😊

🎉 完成!

これでホームページとラズパイPico WHのAPI連携は完了!
長かった今回のプロジェクトはこれにて完成です!🎉✨

実際の本番環境での表示画面はこちらです:

スクリーンショット 2025-05-02 145101.png

さらに詳細な内容やソースコードは、専用のGitHubリポジトリをご覧ください。


🔜 次回の予定

次回はこれまでの取り組みを振り返り、内容をまとめていきます。
会社からのお知らせもあります!

次回もぜひお楽しみに🐣✨

🔗 シリーズリンク

📚 シリーズ全記事はこちら:Qiitaストックページ

12
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?