電子工作
[電子工作] Raspberry Piでネットワーク負荷検知ランプを作った(後編)
はち
更新日:2021/08/11
今回は負荷検知ランプのプログラム編です。
前回も投稿した通り、今回はRaspberry PiのGPIO操作をPHP上から行います。
ランプ構築までの流れ
- まずは、cactiが入っているサーバー上にCSVかXMLファイルを吐き出すシェルを作成します
- 吐き出すシェルをcronで5分毎に実行します
- Raspberry Pi側へ、その出力ファイルを解析するPHPを作成し設置します
- そのPHPをcronで5分毎に実行します
やってることはカナリ地味ですね。
質を上げるなら、検知側はnode.jsなどを使いリアルタイムに拾えると良いかもしれません。
cacti設置サーバー側のシェルファイル
1 |
sudo rrdtool fetch /home/xxxx/cacti/rra/xxxx.rrd AVERAGE -r 300 -s -1h > /home/xxxx/cacti/rra/traffic.csv |
たった一行です。
rrdtool fetchは、rrdtoolでCSV等を出力するコマンドです。
XMLを出力する場合は、これがrrdtool dumpとなります。
Raspberry Pi側に設置するPHPファイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// 初期化 $i = 1; // 予めサーバー側に設置したシェルで吐き出すCSVを読み込む $handle = @fopen("http://192.168.1.22/csv/traffic.csv", "r"); //トラフィック閾値の設定 $arr_alert_traffic = array("10","40","70"); //GPIOピンの指定 $arr_gpio_pins = array("7","17","24","25"); //17:緑、24:黄、25:赤 // ファイルが存在したら処理を開始する if($handle){ while($buffer = fgets($handle)){ //3行目以降を取得する if($i>=3){ // 半角スペース区切りになっているので、分割して配列化しておく $tmp_traffic = explode(" ",$buffer); // -nan(取得出来ていない)状態ではなければ、型変換などを行う if(strcmp($tmp_traffic[1],"-nan")!=0 && strcmp($tmp_traffic[2],"-nan")!=0){ //UNIX TIMEをYMD型に変換する $char_length = strlen($tmp_traffic[0])-1; $tmp_traffic[0] = date("Y/m/d H:i:s",substr($tmp_traffic[0],0,$char_length)); //トラフィック値をMBpsに変換する $tmp_traffic[1] = (float)$tmp_traffic[1]/102400; $tmp_traffic[2] = (float)$tmp_traffic[2]/102400; $arr_traffic[] = $tmp_traffic; } } $i++; } if(!feof($handle)) { echo "fgets()でファイルが取得できませんでした。"; } fclose($handle); } // キーの最大値と最新のトラフィック値を取得しておく $max_keys = max(array_keys($arr_traffic)); $now_traffic = $arr_traffic[$max_keys][2]; //GPIOピンの初期化と準備 foreach($arr_gpio_pins as $key => $value){ file_put_contents('/sys/class/gpio/unexport', $value); file_put_contents('/sys/class/gpio/export', $value); file_put_contents('/sys/class/gpio/gpio'.$value.'/direction', 'out'); } //閾値別LED点灯処理 if($now_traffic > $arr_alert_traffic[2]){ //赤 flushLed(25); }elseif($now_traffic > $arr_alert_traffic[1]){ //黄 flushLed(24); }elseif($now_traffic > $arr_alert_traffic[0]){ //緑 flushLed(17); } //Pinナンバーを指定してLEDをフラッシュさせる+圧電ブザーを鳴らす処理 function flushLed($pin_no){ for($i=0;$i<3;$i++){ file_put_contents('/sys/class/gpio/gpio7/value', 1); file_put_contents('/sys/class/gpio/gpio17/value', 1); file_put_contents('/sys/class/gpio/gpio24/value', 1); file_put_contents('/sys/class/gpio/gpio25/value', 1); usleep(500000); file_put_contents('/sys/class/gpio/gpio7/value', 0); file_put_contents('/sys/class/gpio/gpio17/value', 0); file_put_contents('/sys/class/gpio/gpio24/value', 0); file_put_contents('/sys/class/gpio/gpio25/value', 0); usleep(500000); } file_put_contents('/sys/class/gpio/gpio'.$pin_no.'/value', 1); } |
クソ長いかつレベルの低いプログラムで大変恐縮ですが、簡単に説明すると、閾値10Mを超えたら緑LED、40Mを超えたら黄色LED、70Mを超えたら赤LEDを点灯させます。
稼働確認のため、データ読み込み時には全色のLEDをON/OFF点滅させています。
PHPで操作する、かつ、外部ライブラリを使用しない場合は、gpioのフォルダにfile_put_contentsを用いて、0か1、inかoutを出力することでGPIOを制御出来ます。
外部スイッチの入力などを検知させるには、inを、外部出力の場合はoutをなどなど。
LEDは、非常に簡単で、出力さえ流せば光ります。(途中で電圧をかませるかどうかは置いとくとして)
なので、gpioのピン番号を使用宣言したのち、valueに1を出力すれば勝手に光ります。簡単ですね:)
実際の完成品
雑で恐縮ですがこちらが原型です…。
ランプのような筐体を完成させるのを目的としていましたが、とりあえず動いているのでこのまま運用開始しました。
長くなりましたが見ていただいてありがとうございました。:)