お天気このはちゃん!

この記事は[ConoHa Advent Calendar 2024](https://qiita.com/advent-calendar/2024/conoha)の11日目です。

# 小難しいことしようと思ったけどモチベーションが下がったので、このはちゃんに天気予報を教えてもらっちゃえる素敵な夢のようなサイトをサクッと作っちゃおう!!!!!!!
ってことで、小難しいことはしたくないのでPHPを使っちゃいます。
小難しいことをしようと思ってたけど吹っ切れました!!!!

# 一旦ConoHaを契約しておく
私は慣れたもんで4分で契約できました。
ぜひみなさんもRTAしてみてください。

# サクッとWebサーバーを立てる
小難しいことはしたくない & 自分しか見ない & クライアントとデータのやり取りをしない
ので、この令和の時代にHTTPのみの対応でCloudFlareなどもなしでいきまーーーーーーーーーーー
※公開する場合はちゃんと対策をしましょう。

```bash
sudo yum -y install php php-cli php-common php-devel php-mbstring php-pear php-zip
sudo yum -y install httpd-devel
```
だだだ...

```bash
sudo systemctl start httpd
sudo systemctl enable httpd
sudo firewall-cmd --add-port=80/tcp --zone=public --permanent
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/c0c8382f-2828-77e2-8e92-c46b7e3ca1a8.png)
セキュリティグループ: IPv4v6-Webを追加
(いつの間にかこの機能できてた)

すたっ...
※公開する場合はちゃんｔ((ry

**ここまでの手順をやってなぜか http://[ConoHaのIP]:80 へHTTPアクセスできない場合は一度VPSを再起動してみてください。**

# このはちゃんのガイドラインを**熟読**する
**熟読**してください。
https://conoha.mikumo.com/guideline/
ｼﾞｨｰｰｰｰ

> ウェブサイト、ブログ、ＳＮＳでの本キャラクター及び本サイト（http://conoha.mikumo.com）の紹介
> - https://conoha.mikumo.com/guideline/ 「キャラクター使用のガイドライン」

多分よしっ

気温ごとに季節ごとに違ったこのはちゃんがみたいので、kawaiiイラストをたくさん用意しちゃいましょーーー

`/var/www/html/assets/conoha_kawaii/`
```
image41.png
image44.png
image...


etc...
```

# サクッとデザイン草案を作ろう!!
![design_conoha_weather.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/0e353778-1483-c6ad-f6ba-774bac9998bf.png)
まあ、シンプルに。
ダサくてもこのはちゃんがいるから大丈夫!!!(ry

# 使うAPI
https://www.weatherapi.com/
無料で月に100万リクエストできます。
強い。
APIキーを取得しておきましょう。

# サクッとHTML/CSSを書こう
https://www.flaticon.com/free-icon/
アイコンはこちらからお借りします。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お天気このはちゃん!</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="weather-container">
        <div class="weather-info">
            <div class="temperature">
                <img src="sun-icon.png" alt="Sunny" class="weather-icon">
                <p class="temp-value">9.3℃</p>
            </div>
            <div class="details">
                <div class="detail">
                    <img src="assets/humidity-icon.png" alt="Humidity">
                    <p>53%</p>
                </div>
                <div class="detail">
                    <img src="assets/uv-icon.png" alt="UV Index">
                    <p>0.0</p>
                </div>
                <div class="detail">
                    <img src="assets/wind-icon.png" alt="Wind Speed">
                    <p>38.2km/h</p>
                </div>
            </div>
            <div class="character-images">
                <img src="assets/conoha_kawaii/santa.png" alt="Santa Character" class="character-main">
            </div>
        </div>

        <footer>
            <p>このはちゃんイラスト: ©GMO Internet Group, Inc. | 当サイト内の画像の再利用は著作権法により禁止されています。</p>
            <p>利用画像およびガイドライン: <a href="https://conoha.mikumo.com/guideline/" target="_blank">https://conoha.mikumo.com/guideline/</a></p>
            <p><a href="https://www.flaticon.com/free-icons/wind" title="wind icons">Wind icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/uv" title="uv icons">Uv icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/humidity" title="humidity icons">Humidity icons created by adriansyah - Flaticon</a></p>
        </footer>
    </div>
</body>
</html>
```

そしてCSS
```css
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #fff;
}

.weather-container {
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
    padding: 20px;
}

.weather-header .datetime {
    font-size: 1.5em;
    margin-bottom: 20px;
}

.weather-info {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 30px;
}

.temperature {
    display: flex;
    align-items: center;
    margin-right: 30px;
}

.weather-icon {
    width: 60px;
    height: 60px;
    margin-right: 10px;
}

.temp-value {
    font-size: 2.5em;
    font-weight: bold;
}

.details {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.detail {
    display: flex;
    align-items: center;
    margin: 5px 0;
}

.detail img {
    width: 30px;
    height: 30px;
    margin-right: 10px;
}

.character-images {
    position: relative;
    margin-top: 20px;
}

.character-main {
    width: 300px;
    height: auto;
    margin-bottom: 20px;
}

footer {
    font-size: 0.8em;
    color: #888;
    margin-top: 20px;
}

footer a {
    color: #007BFF;
    text-decoration: none;
}

footer a:hover {
    text-decoration: underline;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/7d81ddb9-7ccb-0a0e-b418-57f91c69714c.png)

うん、本当はレスポンシブにしても...と思ったけども自分のPC以外で開かないと思うのでよし!
※天気のアイコンはAPIのものを使用するのでそのままでOK!

# APIから情報を取得して表示するようにしよう
```
cd /var/www/html
mv index.html index.php
```
まずはphpファイルに変更しましょう。

そして`index.php`を以下のように変えていきます。
```php
<?php
$json = file_get_contents("http://api.weatherapi.com/v1/current.json?key=1c8b53fff94f4cfba1d94743240812&q=Tokyo&aqi=no");
$data = json_decode($json,true);
$degree = $data["current"]["temp_c"];
$weather = $data["current"]["condition"]["icon"];
$humidity = $data["current"]["humidity"];
$wind = $data["current"]["wind_kph"];
$uv = $data["current"]["uv"];
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お天気このはちゃん!</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="weather-container">
        <div class="weather-info">
            <div class="temperature">
            <img src="<?= $weather; ?>" alt="Sunny" class="weather-icon">
            <p class="temp-value"><?= $degree; ?>℃</p>
            </div>
            <div class="details">
                <div class="detail">
                    <img src="assets/humidity-icon.png" alt="Humidity">
                    <p><?= $humidity; ?>%</p>
                </div>
                <div class="detail">
                    <img src="assets/uv-icon.png" alt="UV Index">
                    <p><?= $uv; ?></p>
                </div>
                <div class="detail">
                    <img src="assets/wind-icon.png" alt="Wind Speed">
                    <p><?= $wind; ?>km/h</p>
                </div>
            </div>
            <div class="character-images">
                <img src="assets/conoha_kawaii/santa.png" alt="Santa Character" class="character-main">
            </div>
        </div>

        <footer>
            <p>このはちゃんイラスト: ©GMO Internet Group, Inc. | 当サイト内の画像の再利用は著作権法により禁止されています。</p>
            <p>利用画像およびガイドライン: <a href="https://conoha.mikumo.com/guideline/" target="_blank">https://conoha.mikumo.com/guideline/</a></p>
            <p><a href="https://www.flaticon.com/free-icons/wind" title="wind icons">Wind icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/uv" title="uv icons">Uv icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/humidity" title="humidity icons">Humidity icons created by adriansyah - Flaticon</a></p>
        </footer>
    </div>
</body>
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/4ba89a2f-fe3b-33d0-2045-b2fa9b6350c0.png)

いい感じ。

# このはちゃんがいい感じに変わるようにしよう
1月1日-3日はお正月な雰囲気のこのはちゃん
3月3日はお雛さんなこのはちゃん
7月-8月は夏な雰囲気のこのはちゃん
10月31日はハロウィン
それ以外の
10月-11月は芸術のこのはちゃん
12月1日から12月25日はサンタなこのはちゃん

それ以外の日で気温が15℃-27℃の日はノーマルこのはちゃん
気温27℃以上の日は暑さに怒ってるこのはちゃん
気温15度未満の日は寒さに驚愕してるこのはちゃんを表示しようと思います。

ということで`index.php`を編集します。

```php
<?php
$json = file_get_contents("http://api.weatherapi.com/v1/current.json?key=1c8b53fff94f4cfba1d94743240812&q=Tokyo&aqi=no");
$data = json_decode($json,true);
$degree = $data["current"]["temp_c"];
$weather = $data["current"]["condition"]["icon"];
$humidity = $data["current"]["humidity"];
$wind = $data["current"]["wind_kph"];
$uv = $data["current"]["uv"];

$month = date("n");
$day = date("j");

$conoha_chan = "mini_good.png";

// お正月
if ($month == 1 && $day <= 3) {
    $conoha_chan = "oshogatsu.png";
}
// お雛祭り
elseif ($month == 3 && $day == 3) {
    $conoha_chan = "ohina.png";
}
// 夏の雰囲気
elseif ($month >= 7 && $month <= 8) {
    $conoha_chan = "natsu.png";
}
// ハロウィン
elseif ($month == 10 && $day == 31) {
    $conoha_chan = "haloween.png";
}
// 芸術の秋
elseif ($month == 10 || $month == 11) {
    $conoha_chan = "geijutsu.png";
}
// サンタの期間
elseif ($month == 12 && $day >= 1 && $day <= 25) {
    $conoha_chan = "santa" . rand(0, 2) . ".png";
}
// その他の条件
else {
    if ($degree>= 15 && $degree<= 27) {
        $conoha_chan = "normal.png";
    } elseif ($degree> 27) {
        $conoha_chan = "mini_atsui.png";
    } elseif ($degree< 15) {
        $conoha_chan = "mini_samui.png";
    }
}
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お天気このはちゃん!</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="weather-container">
        <div class="weather-info">
            <div class="temperature">
            <img src="<?= $weather; ?>" alt="Sunny" class="weather-icon">
            <p class="temp-value"><?= $degree; ?>℃</p>
            </div>
            <div class="details">
                <div class="detail">
                    <img src="assets/humidity-icon.png" alt="Humidity">
                    <p><?= $humidity; ?>%</p>
                </div>
                <div class="detail">
                    <img src="assets/uv-icon.png" alt="UV Index">
                    <p><?= $uv; ?></p>
                </div>
                <div class="detail">
                    <img src="assets/wind-icon.png" alt="Wind Speed">
                    <p><?= $wind; ?>km/h</p>
                </div>
            </div>
            <div class="character-images">
            <img src="assets/conoha_kawaii/<?= $conoha_chan; ?>" alt="Santa Character" class="character-main">
            </div>
        </div>

        <footer>
            <p>このはちゃんイラスト: ©GMO Internet Group, Inc. | 当サイト内の画像の再利用は著作権法により禁止されています。</p>
            <p>利用画像およびガイドライン: <a href="https://conoha.mikumo.com/guideline/" target="_blank">https://conoha.mikumo.com/guideline/</a></p>
            <p><a href="https://www.flaticon.com/free-icons/wind" title="wind icons">Wind icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/uv" title="uv icons">Uv icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/humidity" title="humidity icons">Humidity icons created by adriansyah - Flaticon</a></p>
        </footer>
    </div>
</body>
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/ce576101-a448-c390-177d-c8ce21f8f591.png)
よし、いい感じ。

これにて完了!!

# アドバイス
1. おっきな声では言いにくいですが、自己完結でこのはちゃんを愛でるためにこれを作る分には著作権表記は省くことができます(著作権法30条)。
ただしその場合は自分自身でお天気このはちゃんの作成を完結する必要があります。
(例: Web作成が得意な友人に作ってもらう, 作ったものを自分自身(及び一般的には家族)以外に公開するなどはNGです。)
**ただせっかく公式様が使ってもいい条件を決めてくださっているので、それを守ってがっつり作ってがっつりこのは愛を表現・共有する方が楽しいと思います!!**
**このはちゃんを愛でるためであればこの記事内のソースコードなどはご自由に!!**
.
.
2. この天気APIは15分ごと(毎時0,15,30,45分)にリアルタイム情報が更新されるので、データをキャッシュする作りにしておけば大体30日で2900リクエスト弱に収まるので、それっぽいウィジェット風に仕上げることもできるかもしれません。
ちなみにこんな風に改造すると20分に1回更新+?location=<位置>で位置指定が可能な形にできます。
いろいろ改造して常にモニターに表示しておくとかもいいかもしれません。
```php
<?php
$location = ($_GET["location"] == "")? "Tokyo" : $_GET["location"];
$location = htmlspecialchars($location);
$json = file_get_contents("http://api.weatherapi.com/v1/current.json?key=1c8b53fff94f4cfba1d94743240812&q=$location&aqi=no");
$data = json_decode($json,true);
$degree = $data["current"]["temp_c"];
$weather = $data["current"]["condition"]["icon"];
$humidity = $data["current"]["humidity"];
$wind = $data["current"]["wind_kph"];
$uv = $data["current"]["uv"];

$month = date("n");
$day = date("j");

$conoha_chan = "mini_good.png";

// お正月
if ($month == 1 && $day <= 3) {
    $conoha_chan = "oshogatsu.png";
}
// お雛祭り
elseif ($month == 3 && $day == 3) {
    $conoha_chan = "ohina.png";
}
// 夏の雰囲気
elseif ($month >= 7 && $month <= 8) {
    $conoha_chan = "natsu.png";
}
// ハロウィン
elseif ($month == 10 && $day == 31) {
    $conoha_chan = "haloween.png";
}
// 芸術の秋
elseif ($month == 10 || $month == 11) {
    $conoha_chan = "geijutsu.png";
}
// サンタの期間
elseif ($month == 12 && $day >= 1 && $day <= 25) {
    $conoha_chan = "santa" . rand(0, 2) . ".png";
}
// その他の条件
else {
    if ($degree>= 15 && $degree<= 27) {
        $conoha_chan = "normal.png";
    } elseif ($degree> 27) {
        $conoha_chan = "mini_atsui.png";
    } elseif ($degree< 15) {
        $conoha_chan = "mini_samui.png";
    }
}
$isError = false;
if(empty($weather)){
    $isError = true;
}

?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お天気このはちゃん!</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="weather-container">
        <div class="weather-info">
        <?php if(!$isError){ ?>
            <div class="temperature">
            <img src="<?= $weather; ?>" alt="Sunny" class="weather-icon">
            <p class="temp-value"><?= $degree; ?>℃</p>
            </div>
            <div class="details">
                <div class="detail">
                    <img src="assets/humidity-icon.png" alt="Humidity">
                    <p><?= $humidity; ?>%</p>
                </div>
                <div class="detail">
                    <img src="assets/uv-icon.png" alt="UV Index">
                    <p><?= $uv; ?></p>
                </div>
                <div class="detail">
                    <img src="assets/wind-icon.png" alt="Wind Speed">
                    <p><?= floor(($wind / 60 / 60)*1000); ?>m/s</p>
                </div>
            </div>
            <div class="character-images">
            <img src="assets/conoha_kawaii/<?= $conoha_chan; ?>" alt="Santa Character" class="character-main">
            </div>
        <?php } else { ?>
            <div class="character-images">
            <img src="assets/conoha_kawaii/error.png" alt="Santa Character" class="character-main">
            </div>
        <?php } ?>
        </div>

        <footer>
            <p style="color:#666;" class="location"><?php echo $isError? "位置情報が正しくありません。" : $location; ?> | <?php echo "更新時刻: ".date("H:i:s"); ?></p>
            <p>このはちゃんイラスト: ©GMO Internet Group, Inc. | 当サイト内の画像の再利用は著作権法により禁止されていま す。</p>
            <p>利用画像およびガイドライン: <a href="https://conoha.mikumo.com/guideline/" target="_blank">https://conoha.mikumo.com/guideline/</a></p>
            <p><a href="https://www.flaticon.com/free-icons/wind" title="wind icons">Wind icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/uv" title="uv icons">Uv icons created by Freepik - Flaticon</a></p>
            <p><a href="https://www.flaticon.com/free-icons/humidity" title="humidity icons">Humidity icons created by adriansyah - Flaticon</a></p>
        </footer>
    </div>
    <script> setTimeout(()=>{ location.reload(); },1000*60*20); </script>
</body>
</html>
```
# ギャラリー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/532032e1-f217-352b-bf37-d0f7db1440ee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/dc14fdeb-ab50-f2fe-d90c-24fd62a797a9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/88afd617-58a8-91b6-5dc1-4d42a576f4ce.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/20122ec3-95c2-b224-4195-4a627c5f25c5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351582/3aa9c61a-264e-f982-ed58-b690a236d96b.png)
drop-shadowつけてもよきですね!
img要素に`filter: drop-shadow(15px 5px 6px #ccc);`みたいな感じでCSSを貼れば作れます。