第30回 Webから天気予報と鉄道運行状況を取得してLED点滅制御する

今回は、今までに動作確認・アルゴリズム確認で作成したプログラムをまとめて、Webから情報取得をしてLED制御をするプログラムにまとめてみます。

今回の説明内容

今までの試作で一通りの動作確認とアルゴリズムの確認もできましたので、あとは組み合わせれば動くはずです!

点滅バターンを定義してLEDを点滅制御することと、Webから取得した情報をもとに点滅パターン作成をしましたので、これを単純に組み合わせれば動くはずです。

今回の説明内容は以下になります。

  • プログラムの構成
  • PHPで鉄道運行情報文字列解析プログラムを作成
  • Pythonで鉄道運行情報文字列解析プログラムを作成

 

プログラムの構成

今まで試作したプログラムを単純に組み合わせただけでは、あとの作業が大変になりますのでプログラムの構成を検討しておきます。

Webから情報を取得して、点滅パターン配列(PHP)/点滅パターンリスト(Python)を作成して、点滅制御、という処理であれば、今までのプログラムを合体させればOKです。ただ最終的には、指定した時刻にWebから天気予報情報・鉄道運行情報を取得したり、スイッチを押した時に再度Webから情報を取得、という処理も追加する予定です。ということは、Webから情報を取得して点滅パターンを生成する部分は関数にしておいた方がいいですよね。

ということで、今回新しく出てくる内容はPHP/Pythonの関数程度で特に検討項目はありませんので、早速プログラムを作ってみます。

 

PHPで鉄道運行情報文字列解析プログラムを作成

PHPでは以下のように作成してみました。ただ、天気予報情報解析の部分は冗長なのでこれをさらに関数にするなど工夫した方がいいですね。

解説が必要と思われるところについてはプログラムの後に説明します。なお、今まで解説した部分については説明をしていませんので、過去記事をご参照ください。

#!/usr/bin/php

<?php

// 天気予報情報の取得地域設定 ($cityに地域コードを設定)
$city = "140010";  // 横浜

// 鉄道運行状況情報取得する路線名設定
$line_name = "山手線";

// LED点滅パターンの基本パターンを連想配列に定義
$basic_pat = [
    "on"    => [1, 1, 1, 1], // 点灯したままのパターン
    "off"   => [0, 0, 0, 0], // 消灯したままのパターン
    "blink" => [0, 1, 0, 1], // 点滅するパターン
];

// LEDのGPIO番号を連想配列に定義
$gpio_led = [
    "fine"  => 21, // 晴れ用LED
    "cloud" => 20, // 曇り用LED
    "rain"  => 16, // 雨用LED
    "snow"  => 12, // 雪用LED
    "rail_green" => 25, // 鉄道運行状況用 - 緑
    "rail_blue"  => 24, // 鉄道運行状況用 - 青
    "rail_red"   => 23, // 鉄道運行状況用 - 赤
];

// GPIOモードの設定
// $gpio_ledで定義したすべてのピンを出力モードに設定する
foreach($gpio_led as $led_name => $gpio_pin_number) {
    `gpio -g mode $gpio_pin_number out`;
}

// LED点滅パターン用に空の配列を作成
$led_pat = [];

// 天気予報情報の取得とLED点滅パターンの設定
SetWeatherLedPattern();

// 鉄道運行状況情報の取得とLED点滅パターンの設定
SetRailwayInfoLedPattern();

// 全体で3回繰り返す
for($repeat=0; $repeat<3; $repeat++) {
    // LED表示バターン配列$led_patに入っている要素数分、点滅制御する
    for($num=0; $num<count($led_pat["fine"]); $num++) {
        // 各LEDの点灯・消灯の出力設定をする
        foreach($gpio_led as $led_name => $gpio_pin_number) {
            $value = $led_pat[$led_name][$num];
            `gpio -g write $gpio_pin_number $value`;
        }
        // 0.25秒間待つ
        usleep(250000);
    }
}

// GPIOピンの出力を0にする
foreach($gpio_led as $weather => $gpio) {
    `gpio -g write $gpio 0`;
}

// --------- 関数 ---------

// 天気予報情報の取得とLED点滅パターンの設定関数
function SetWeatherLedPattern()
{
    global $city;
    global $basic_pat, $led_pat;
    
    // 天気情報の取得URLを生成
    $url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=$city";

    // 天気データ取得
    // 最初に指定URLのデータを取得
    $response = file_get_contents($url);
    // jsonデータのためjson_decode関数で連想配列に変換
    $weather = json_decode($response,true);
    // 天気予報文字列の取得
    $forecast = $weather["forecasts"][0]["telop"];
    
    // デバッグ用
    // 天気予報文字列の表示
    echo "天気予報文字列: " . $forecast . "\n";

    // 解析対象外の文字を削除
    $forecast = str_replace(["大", "暴風", "雷"], "", $forecast);

    // 「一時」を「時々」に置換
    $forecast = str_replace("一時", "時々", $forecast);

    // 「雨か雪」と「雪か雨」をそれぞれ「雨」と「雪」に変換
    $forecast = str_replace("雨か雪", "雨", $forecast);
    $forecast = str_replace("雪か雨", "雪", $forecast);

    // 晴れの解析
    // 最初に「晴」の完全一致を確認
    if( strcmp($forecast, "晴れ") == 0 ) {
        // 「晴れ」に完全一致していれば、晴のLEDは点灯したまま
        $led_pat += [ "fine" => array_merge($basic_pat["on"], $basic_pat["on"], $basic_pat["on"]) ]; 
    } else {
        // 「晴れ」に完全一致していなければ、「晴」の文字が含まれているか確認
        $pos = strpos($forecast, "晴");
        if ( $pos !== false ) {
            // 「晴」の文字が含まれている場合の処理
            if ( $pos == 0 ) {
                // 先頭に「晴」がある場合
                $led_pat += [ "fine" => array_merge($basic_pat["on"], $basic_pat["off"], $basic_pat["off"]) ];
            } else {
                // 先頭にない場合は「時々晴」と「のち晴」を確認
                if ( strpos($forecast, "時々晴") !== false ){
                    $led_pat += [ "fine" => array_merge($basic_pat["off"], $basic_pat["blink"], $basic_pat["off"]) ];
                } else {
                    if ( strpos($forecast, "のち晴") !== false ){
                        $led_pat += [ "fine" => array_merge($basic_pat["off"], $basic_pat["on"], $basic_pat["off"]) ];
                    } else {
                        // いずれでもない場合は消灯にする
                        $led_pat += [ "fine" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];  
                    }
                }
            }
        } else {
            // 予報文字列に晴れはないのでLEDは消灯したまま
            $led_pat += [ "fine" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
        }
    }

    // 曇りの解析
    if( strcmp($forecast, "曇り") == 0 ) {
        $led_pat += [ "cloud" => array_merge($basic_pat["on"], $basic_pat["on"], $basic_pat["on"]) ]; 
    } else {
        $pos = strpos($forecast, "曇");
        if ( $pos !== false ) {
            if ( $pos == 0 ) {
                $led_pat += [ "cloud" => array_merge($basic_pat["on"], $basic_pat["off"], $basic_pat["off"]) ];
            } else {
                if ( strpos($forecast, "時々曇") !== false ) {
                    $led_pat += [ "cloud" => array_merge($basic_pat["off"], $basic_pat["blink"], $basic_pat["off"]) ];
                } else {
                    if ( strpos($forecast, "のち曇") !== false ) {
                        $led_pat += [ "cloud" => array_merge($basic_pat["off"], $basic_pat["on"], $basic_pat["off"]) ];
                    } else {
                        // いずれでもない場合は消灯にする
                        $led_pat += [ "cloud" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];  
                    }
                }
            }
        } else {
            $led_pat += [ "cloud" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
        }
    }

    // 雨の解析
    if( strcmp($forecast, "雨") == 0 ) {
        $led_pat += [ "rain" => array_merge($basic_pat["on"], $basic_pat["on"], $basic_pat["on"]) ]; 
    } else {
        $pos = strpos($forecast, "雨");
        if ( $pos !== false ) {
            if ( $pos == 0 ) {
                $led_pat += [ "rain" => array_merge($basic_pat["on"], $basic_pat["off"], $basic_pat["off"]) ];
            } else {
                if ( strpos($forecast, "時々雨") !== false ) {
                    $led_pat += [ "rain" => array_merge($basic_pat["off"], $basic_pat["blink"], $basic_pat["off"]) ];
                } else {
                    if ( strpos($forecast, "のち雨") !== false ) {
                        $led_pat += [ "rain" => array_merge($basic_pat["off"], $basic_pat["on"], $basic_pat["off"]) ];
                    } else {  
                        // いずれでもない場合は消灯にする
                        $led_pat += [ "rain" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];  
                    }
                }
            }
        } else {
            $led_pat += [ "rain" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
        }
    }

    // 雪の解析
    if( strcmp($forecast, "雪") == 0 ) {
        $led_pat += [ "snow" => ["on", "on", "on"] ]; 
    } else {
        $pos = strpos($forecast, "雪");
        if ( $pos !== false ) {
            if ( $pos == 0 ) {
                $led_pat += [ "snow" => array_merge($basic_pat["on"], $basic_pat["off"], $basic_pat["off"]) ];
            } else {
                if ( strpos($forecast, "時々雪") !== false ) {
                    $led_pat += [ "snow" => array_merge($basic_pat["off"], $basic_pat["blink"], $basic_pat["off"]) ];
                } else {
                    if ( strpos($forecast, "のち雪") !== false ) {
                        $led_pat += [ "snow" => array_merge($basic_pat["off"], $basic_pat["on"], $basic_pat["off"]) ];
                    } else {  
                        // いずれでもない場合は消灯にする
                        $led_pat += [ "snow" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];  
                    }
                }
            }
        } else {
            $led_pat += [ "snow" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
        }
    }
}



// 鉄道運行状況情報の取得とLED点滅パターンの設定関数
function SetRailwayInfoLedPattern()
{
    global $line_name;
    global $basic_pat, $led_pat;

    // Yahoo! Japan運行情報のURL
    // 以下は関東地方の運行情報URL
    $url = "http://transit.yahoo.co.jp/traininfo/area/4/";

    // Yahoo! Japan運行情報ページのHTMLデータ取得
    // ただしテスト用なのでWebからの取得はせずにローカルに保存してあるファイルを読み込む
    // $railway_html = file_get_contents($url);
    $railway_html = file_get_contents("./index.html");

    // 取得したHTMLデータを改行で分割して配列に格納
    $railway_info = explode("\n", $railway_html);

    // 配列に入れたHTMLデータ各行を解析
    for($i=0; $i<count($railway_info)-1; $i++) {
        // 情報取得する路線名文字列が含まれているかチェック
        $pos = strpos($railway_info[$i], $line_name."</a></td>");
        if ($pos !== false) {
            // 含まれていれば次の行に運行情報文字列があるので
            // 運行情報に合わせたLEDの色とパターンを格納
            // まず「平常」が含まれるかチェック
            $pos = strpos($railway_info[$i+1], "平常");
            if($pos !== false) {
                // 平常運転であればLED色は緑で点灯
                $led_pat += [ "rail_green" => array_merge($basic_pat["on"], $basic_pat["on"], $basic_pat["on"]) ];
                $led_pat += [ "rail_blue"  => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
                $led_pat += [ "rail_red"   => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
                // デバッグ用
                echo "鉄道運行状況文字列: 平常\n";
            } else {
                // 平常運転でなければ「遅延」が含まれるかチェック
                $pos = strpos($railway_info[$i+1], "遅延");
                if($pos !== false) {
                    // 遅延であればLED色は黄色で点滅
                    $led_pat += [ "rail_green" => array_merge($basic_pat["blink"], $basic_pat["blink"], $basic_pat["blink"]) ];
                    $led_pat += [ "rail_blue"  => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
                    $led_pat += [ "rail_red"   => array_merge($basic_pat["blink"], $basic_pat["blink"], $basic_pat["blink"]) ];
                    // デバッグ用
                    echo "鉄道運行状況文字列: 遅延\n";
                } else {
                    // 平常運転、遅延でもなければLEDを赤点滅して警告する
                    $led_pat += [ "rail_green" => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
                    $led_pat += [ "rail_blue"  => array_merge($basic_pat["off"], $basic_pat["off"], $basic_pat["off"]) ];
                    $led_pat += [ "rail_red"   => array_merge($basic_pat["blink"], $basic_pat["blink"], $basic_pat["blink"]) ];
                    // デバッグ用
                    echo "鉄道運行状況文字列: 異常(運行見合わせやその他)\n";
                }
            }
        }
    }
}


?>

24〜26行目:

鉄道運行状況を表示するLEDはフルカラーLEDで、1個のLEDに緑/青/赤のLEDが入っていますのでここで定義しておきます。例えば電車に遅延が発生している場合、黄色で点滅しますが、この場合は赤と緑を同時に点灯させます。

39行目:

天気予報情報の取得とLED点滅パターンの設定は SetWeatherLedPatter() という関数にしています。関数の実態は66行目以降にあります。

42行目:

天気予報情報取得と同様に、鉄道運行状況のLED点滅パターンの設定は SetRailwayInfoLedPatter() という関数にしています。関数の実態は207行目以降にあります。

45〜56行目:

SetWeatherLedPatterh()とSetRailwayInfoLedPatter()関数の呼び出しで、点滅パターンは設定されていますので、このブロックでLEDの点滅制御をします。なお、まだ確認段階ですので3回繰り返して終了します。

218・219行目:

鉄道運行状況情報の取得はYahoo! Japanの運行状況サイトをWebスクレイピングしていますので、確認段階ではwgetコマンドで取得しておいたHTMLデータを使用しています。本運用の際は、218行目を有効にして、219行目はコメントアウトします。

235〜237行目:

以前の記事で、鉄道運行状況の文字列からLED点滅パターンに変換した際は、単にLEDの色とパターンを決定しただけですが、今回はLEDの色を制御する必要がありますので、各判定結果をもとに、青/緑/赤の各色の点滅パータンを設定します。

ということで、ほとんど解説するところはないと思いますが、不明点がありましたらコメント欄でご質問ください。

上に掲載したプログラムは実際に動作確認したものをコピペしています。2016年1月23(土)に動作確認をしてこの記事を書いているのですが、東京地方では比較的珍しい雪の予報でしたので、ピンク色のLEDの発光を見ることができました。

 

Pythonで鉄道運行情報文字列解析プログラムを作成

PHPのプログラムと同様の構成でPythonでプログラムを作成してみました。解説が必要と思われるところはプログラムの後に説明しています。

#!/usr/bin/python
# coding: utf-8

# モジュールインポート
import RPi.GPIO as GPIO
import time
import json, urllib2

# 天気予報情報の取得地域設定 ($cityに地域コードを設定)
city = '140010' #横浜

# 鉄道運行状況情報取得する路線名設定
lineName = '山手線'

# LED点滅パターンの基本パターンを辞書に定義
basicPat = {
    'on':    (1, 1, 1, 1), # 点灯したままのパターン
    'off':   (0, 0, 0, 0), # 消灯したままのパターン
    'blink': (0, 1, 0, 1)  # 点滅するパターン
}

# LEDのGPIO番号を連想配列に定義
gpioLed = {
    'fine':  21, # 晴れ用LED
    'cloud': 20, # 曇り用LED
    'rain':  16, # 雨用LED
    'snow':  12, # 雪用LED
    'rail_green': 25, # 鉄道運行状況用 - 緑
    'rail_blue' : 24, # 鉄道運行状況用 - 青
    'rail_red'  : 23  # 鉄道運行状況用 - 赤
}

# GPIOモード設定
# GPIO番号指定をBCM(GPIO番号)に設定
GPIO.setmode(GPIO.BCM)

# gpioLedで定義したすべてのピンを出力モードに設定する
gpioPins = gpioLed.values()
GPIO.setup(gpioPins, GPIO.OUT)



# --------- 関数 ---------

# 天気予報情報の取得とLED点滅パターンの設定関数
def SetWeatherLedPattern():
    global city
    global basicPat, ledPat
    
    # 天気情報の取得URLを生成
    url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=%s' % city

    try:
        # 天気データ取得
        # 最初に指定URLのデータ取得
        response = urllib2.urlopen(url)
        # jsonデータ取得
        weather = json.loads(response.read())
        # 天気予報文字列の取得
        forecast = weather['forecasts'][0]['telop']
        forecast = forecast.encode('utf-8')

    finally:
        response.close()

    # 解析対象外の文字を削除
    forecast = forecast.replace('大', '').replace('暴風', '').replace('雷', '')

    # 「一時」を「時々」に置換
    forecast = forecast.replace('一時', '時々')

    # 「雨か雪」と「雪か雨」をそれぞれ「雨」と「雪」に置換
    forecast = forecast.replace('雨か雪', '雨')
    forecast = forecast.replace('雪か雨', '雪')

    # 晴れの解析
    # 最初に「晴れ」の完全一致を確認
    if forecast == '晴れ':
        # 「晴れ」に完全一致していれば、晴れのLEDは点灯したままのパターン
        ledPat.update({'fine': basicPat['on'] + basicPat['on'] + basicPat['on']})
    else:
        # 「晴」の文字が含まれているか確認
        pos = forecast.find('晴')
        if pos >= 0:
            # 「晴」が含まれている場合
            if pos == 0:
                # 先頭に「晴」がある場合
                ledPat.update({'fine': basicPat['on'] + basicPat['off'] + basicPat['off']})
            else:
                # 先頭に「晴」がない場合は「時々晴」と「のち晴」を確認
                if forecast.find('時々晴') > 0:
                    ledPat.update({'fine': basicPat['off'] + basicPat['blink'] + basicPat['off']})
                else:
                    if forecast.find('のち晴') > 0:
                        ledPat.update({'fine': basicPat['off'] + basicPat['on'] + basicPat['off']})
                    else:
                        # いずれでもない場合は消灯する
                        ledPat.update({'fine': basicPat['off'] + basicPat['off'] + basicPat['off']})
        else:
            # 予報文字列に「晴」はないのでLEDは消灯
            ledPat.update({'fine': basicPat['off'] + basicPat['off'] + basicPat['off']})

    # 曇りの解析
    if forecast == '曇り':
        ledPat.update({'cloud': basicPat['on'] + basicPat['on'] + basicPat['on']})
    else:
        pos = forecast.find('曇')
        if pos >= 0:
            if pos == 0:
                ledPat.update({'cloud': basicPat['on'] + basicPat['off'] + basicPat['off']})
            else:
                if forecast.find('時々曇') > 0:
                    ledPat.update({'cloud': basicPat['off'] + basicPat['blink'] + basicPat['off']})
                else:
                    if forecast.find('のち曇') > 0:
                        ledPat.update({'cloud': basicPat['off'] + basicPat['on'] + basicPat['off']})
                    else:
                        ledPat.update({'cloud': basicPat['off'] + basicPat['off'] + basicPat['off']})
        else:
            ledPat.update({'cloud': basicPat['off'] + basicPat['off'] + basicPat['off']})

    # 雨の解析
    if forecast == '雨':
        ledPat.update({'rain': basicPat['on'] + basicPat['on'] + basicPat['on']})
    else:
        pos = forecast.find('雨')
        if pos >= 0:
            if pos == 0:
                ledPat.update({'rain': basicPat['on'] + basicPat['off'] + basicPat['off']})
            else:
                if forecast.find('時々雨') > 0:
                    ledPat.update({'rain': basicPat['off'] + basicPat['blink'] + basicPat['off']})
                else:
                    if forecast.find('のち雨') > 0:
                        ledPat.update({'rain': basicPat['off'] + basicPat['on'] + basicPat['off']})
                    else:
                        ledPat.update({'rain': basicPat['off'] + basicPat['off'] + basicPat['off']})
        else:
            ledPat.update({'rain': basicPat['off'] + basicPat['off'] + basicPat['off']})


    # 雪の解析
    if forecast == '雪':
        ledPat.update({'snow': basicPat['on'] + basicPat['on'] + basicPat['on']})
    else:
        pos = forecast.find('雪')
        if pos >= 0:
            if pos == 0:
                ledPat.update({'snow': basicPat['on'] + basicPat['off'] + basicPat['off']})
            else:
                if forecast.find('時々雪') > 0:
                    ledPat.update({'snow': basicPat['off'] + basicPat['blink'] + basicPat['off']})
                else:
                    if forecast.find('のち雪') > 0:
                        ledPat.update({'snow': basicPat['off'] + basicPat['on'] + basicPat['off']})
                    else:
                        ledPat.update({'snow': basicPat['off'] + basicPat['off'] + basicPat['off']})
        else:
            # 予報文字列に「雪」はないのでLEDは消灯
            ledPat.update({'snow': basicPat['off'] + basicPat['off'] + basicPat['off']})

# 鉄道運行状況情報の取得とLED点滅パターンの設定関数
def SetRailwayInfoLedPattern():
    global lineName
    global basicPat, ledPat

    # Yahoo! Japan運行情報ページのURL
    # 以下は関東地方の運行情報URL
    url = 'http://transit.yahoo.co.jp/traininfo/area/4/'

    # Yahoo! Japan運行情報ページのHTMLデータ取得して1行ずつリストに格納
    # response = urllib2.urlopen(url)
    # htmlData = response.read()
    # railwayInfo = htmlData.split('\n')

    # ただしテスト用なのでWebからの取得はせずにローカルに保存してあるファイルを読み込む
    # index.htmlをオープンして読み込み、1行ずつリストに格納
    f = open('./index.html')
    htmlData = f.read()
    f.close()
    railwayInfo = htmlData.split('\n')

    # リストに入れたHTMLデータ各行を解析
    for i in range(0, len(railwayInfo)):
        # 情報取得する路線名文字列が含まれているかチェック
        pos = railwayInfo[i].find(lineName + '</a></td>')
        if pos >= 0:
            # 含まれていれば次の行に運行情報文字列があるので
            # 運行情報に合わせたLEDの色とパターンを格納
            # まず「平常」が含まれるかチェック
            pos = railwayInfo[i+1].find('平常')
            if pos >= 0:
                # 平常運転であればLED色は緑で点灯
                ledPat.update({'rail_green': basicPat['on'] + basicPat['off'] + basicPat['off']})
                ledPat.update({'rail_blue' : basicPat['off'] + basicPat['off'] + basicPat['off']})
                ledPat.update({'rail_red'  : basicPat['off'] + basicPat['off'] + basicPat['off']})
            else:
                # 平常運転でなければ「遅延」が含まれるかチェック
                pos = railwayInfo[i+1].find('遅延')
                if pos >= 0:
                    # 遅延であればLED色は黄色で点滅
                    ledPat.update({'rail_green': basicPat['blink'] + basicPat['blink'] + basicPat['blink']})
                    ledPat.update({'rail_blue' : basicPat['off'] + basicPat['off'] + basicPat['off']})
                    ledPat.update({'rail_red'  : basicPat['blink'] + basicPat['blink'] + basicPat['blink']})
                else:
                    # 平常運転、遅延でもなければLEDを赤点滅して警告する
                    ledPat.update({'rail_green': basicPat['off'] + basicPat['off'] + basicPat['off']})
                    ledPat.update({'rail_blue' : basicPat['off'] + basicPat['off'] + basicPat['off']})
                    ledPat.update({'rail_red'  : basicPat['blink'] + basicPat['blink'] + basicPat['blink']})



#   LED点滅処理
try:
    # 点滅パターン格納用の辞書を初期化
    ledPat = {}

    # 天気予報情報の取得とLED点滅パターンの設定
    SetWeatherLedPattern()

    # 鉄道運行状況情報の取得とLED点滅パターンの設定
    SetRailwayInfoLedPattern()

    # 全体で3回繰り返す
    for repeat in range(0, 3):
        # 天気表示パターンledPatに入っている点滅パターンの要素数分、点滅制御する
        for num in range(0, len(ledPat['fine'])):
            # 各LEDの点灯・消灯の出力設定をする
            for ledName, gpioPinNumber in gpioLed.items():
                GPIO.output(gpioPinNumber, ledPat[ledName][num])

            # 0.25秒待つ
            time.sleep(0.25)

# ---------------
#   GPIOリセット
# ---------------
finally:
    GPIO.cleanup()

28〜30行目:

PHPのプログラムと同様、鉄道運行状況を表示するLEDはフルカラーLEDで、1個のLEDに緑/青/赤のLEDが入っていますのでここで定義しておきます。例えば電車に遅延が発生している場合、黄色で点滅しますが、この場合は赤と緑を同時に点灯させます。

45行目:

天気予報情報の取得とLED点滅パターンの設定の関数定義部分です。SetWeatherLedPatter() という関数にしています。

61行目:

Weather Hacksから取得した天気予報の文字列はUnicode表現で、その文字列をそのままPythonで処理するとエラーになります(実はここでちょっとハマってました)。.encode('utf-8')としてUTF-8のエンコーディングに変換しておく必要があります。

163行目:

天気予報情報取得と同様に、鉄道運行状況のLED点滅パターンの設定は SetRailwayInfoLedPatter() という関数にしています。関数の実態は207行目以降にあります。

225〜233行目:

SetWeatherLedPatterh()とSetRailwayInfoLedPatter()関数の呼び出しで、点滅パターンは設定されていますので、このブロックでLEDの点滅制御をします。なお、まだ確認段階ですので3回繰り返して終了します。

ということで、Pythonのプログラムもほとんど解説するところはないと思いますが、不明点がありましたらコメント欄でご質問ください。

ずいぶん簡素な説明になってしまいました。。。

次回は情報を取得する時刻を設定しておき、その時刻がきたらWebから情報取得してLEDの点滅パターンの更新をしてみたいと思います。また鉄道運行状況は刻々と変わることもあるので、スイッチを押すと情報更新するようにもしてみたいと思います。

« »