ブラウザのJavaScriptをONにしてアクセス願います

絶縁監視装置の発報をLINEへ通知する
Total Access: 7797155


絶縁監視装置の発報をLINEへ通知する

このページの絶監はムサシインテックの監視王シリーズの通報メール例を用いていますが,どのメーカ製であっても基本的には問題ありませんし,メーカの混在利用も可です.

絶縁監視装置を使っていると当然漏電のたびにメールで通知が来ますが,故障の発生・復帰を繰り返したりする場合メールだとどうしても流れを追いづらいかと思います.
例えば,Android上のGMail(スレッド表示ON)では下図の通りで,メールを1個ずつ開いて確認しないとならないし面倒です.そして通知が遅いです.

これを多少でも見やすくなるように,まずはLINEに通知することを考えます.


1.LINE Notify API実装

LINE Notify準備

  1. LINE Notify に行ってLINE IDでログイン
  2. マイページに行く.
  3. アクセストークン発行
  4. トークンをメモしておく

サーバ準備

ここでは,さくらサーバでの設定とする.
  1. PEAR をサーバにインストールする
  2. サーバコントロールパネル に行って,絶監通知メール受信用のメールアドレスを新規作成
  3. .mailfilterを編集する

    to "| /usr/local/bin/php -q /home/アカウント名/MailBox/新規作成したメールアドレスの@より左側/send2line.php"

    とする.エンコードはEUCでアップロードパーミッション600,
    これでメール新着をトリガにして send2line.php がキックされます.

以上で準備完了.

メール新着トリガでキックされるPHPスクリプト(send2line.php)を作成

#!/usr/local/bin/php -q

<?php

    //PEARインストールパスにより適宜変える.絶対パスで指定.
    require_once '/home/haiden/www/****/****/Mail/mimeDecode.php'; 

    // カレントの言語を日本語に設定する
    mb_language("ja");
 
    // 内部文字エンコードを設定する
    mb_internal_encoding("shift-jis");
 
    // メールデータ取得
    $params['include_bodies'] = true;
    $params['decode_bodies']  = true;
    $params['decode_headers'] = true;
    $params['input'] = file_get_contents("php://stdin");
    $params['crlf'] = "\r\n";
    $structure = Mail_mimeDecode::decode($params);
 
    //送信者のメールアドレスを抽出
    $mail = $structure->headers['from'];
    $mail = addslashes($mail);
    $mail = str_replace('"','',$mail);
 
    //署名付きの場合の処理を追加
    preg_match("/<.*>/",$mail,$str);
    if($str[0]!=""){
        $str=substr($str[0],1,strlen($str[0])-2);
        $mail = $str;
    }
 
    // 件名を取得
    $diary_subject = $structure->headers['subject'];
 
    switch(strtolower($structure->ctype_primary)){
        case "text": // シングルパート(テキストのみ)
            $diary_body = $structure->body;
            break;
        case "multipart":  // マルチパート(画像付き)
            foreach($structure->parts as $part){
                switch(strtolower($part->ctype_primary)){
                    case "text": // テキスト
                        $diary_body = $part->body;
                        break;
                    case "image": // 画像
                        //画像の拡張子を取得する(小文字に変換
                        $type = strtolower($part->ctype_secondary);
                        //JPEGチェック(GIFやPNG形式の画像チェックなども可
                        if($type != "jpeg" and $type != "jpg"){
                            continue;
                        }
 
                        //添付内容をファイルに保存
                        $fp = fopen("/tmp/picture.jpg" . $type,"w" );
                        $length = strlen( $part->body );
                        fwrite( $fp, $part->body, $length );
                        fclose( $fp );
                        break;
                }
            }
            break;
            default:
            $diary_body = "";
    }


define('LINE_API_URL'  ,"https://notify-api.line.me/api/notify");
define('LINE_API_TOKEN','発行したトークン');

function post_message($message){

    $data = array(
                        "message" => $message
                     );
    $data = http_build_query($data, "", "&");

    $options = array(
        'http'=>array(
            'method'=>'POST',
            'header'=>"Authorization: Bearer " . LINE_API_TOKEN . "\r\n"
                      . "Content-Type: application/x-www-form-urlencoded\r\n"
                      . "Content-Length: ".strlen($data)  . "\r\n" ,
            'content' => $data
        )
    );
    $context = stream_context_create($options);
    $resultJson = file_get_contents(LINE_API_URL,FALSE,$context );
    $resutlArray = json_decode($resultJson,TRUE);
    if( $resutlArray['status'] != 200)  {
        return false;
    }
    return true;
}

//エンコードをUTFにする
$diary_subject = mb_convert_encoding($diary_subject, "UTF-8", "auto");
$diary_body = mb_convert_encoding($diary_body, "UTF-8", "auto");

	//タグを削除
	$reg = '/<("[^"]*"|\'[^\']*\'|[^\'">])*>/';
	$diary_body = preg_replace($reg, '', $diary_body);

	//複数改行を置き換え
	$reg = '/(\n|\r|\r\n)+/us';
	$diary_body = preg_replace($reg,"\n",$diary_body);

	//全角スペースを半角に
	$text = str_replace(' ', ' ', $text);


//LINEへ送信
post_message("\n".$diary_subject."\n".$text);

?>

以上により受信メールの件名・本文が下図の通りLINEにプッシュ配信される.


2.メールログ機能

前項まででとりあえずはLINEトーク上で確認できるようになって,メールで見るよりは多少マシになります.通知も非常に速くなります.
ただ,やはり大量の発報がある場合だと何となく経過を追いづらいってことでログ機能を付加していきます.ログで一覧で見れた方が状況把握しやすくなります.

コード的には,

// ------------------------------------------------------------
// Logファイル作成用処理
// ------------------------------------------------------------
$new_line = "$diary_subject $text\n";

//txtファイルを全て読み出し
$data = file('/home/******/www/hogehoge/maillog.log');
$data[] = $new_line;
$lines = count($data); //現在の行数を取得
if($lines >= 501){ //指定行以上存在するなら,一番古いもの(配列の一番先頭)を削除
	unset($data[0]);
}
//txt全部の行をファイルに書き込み
$fp = fopen('/home/******/www/hogehoge/maillog.log', 'a+');
		if (flock($fp, LOCK_EX)) {  // 排他ロックを確保します
		@flock($fp,LOCK_EX); // 排他ロックをかける
			ftruncate($fp, 0); //ファイルを0バイトにする
			foreach($data as $datum){
				fwrite($fp, $datum);
			}
		} else {
		    echo "ファイル排他ロック不可";
		}
	fclose($fp);
// ------------------------------------------------------------

みたいな感じで,メール本文の改行を除去したり,色々と整形した後,ログファイルに書き込んで行きます.当然ですが排他ロック等は必ずやっておくこと.
あと,$lines >= 501 で500行以上存在するなら,一番古いものを削除しておきます.
最大500行とした理由は特にありませんが,あまり大きいとファイルが重くなるってだけです…特に平文でロギングしてるので,これがバイナリとかでやれば全然軽くなるものの単に面倒くさいからです.

一方,このログファイルを読み込む側のスクリプトは,

$data = file('./maillog.log');
$num = sizeof($data);

echo "<div class=\"scroll\">\n";
for($i=$num-1; $i>=0; $i--){
	echo ("<nobr>".$data[$i]."</nobr><br>\n");
}
echo "</div>\n";

↑のコードみたく,Forループでカウンタを減算してファイルを逆順から(一番上が最新になるように)読み込みしてやれば以下のようにブラウザで確認可能.メールで1通ずつ確認するよりずっとラクになります.


以上,こういう実装をしておけば,漏電故障が発生した際にLINEに即通知が飛んできて,そのメッセージ内のアンカからメールログの履歴の一覧を一発で確認できるようになって圧倒的に便利です.
もちろん,絶監のメーカごとに用意されているであろう管理画面からログインして通報一覧にアクセスするみたいな感じでも良いのですが,いちいち面倒です.

絶監を何十台も付けて運用している方なら是非こういった仕組みを実装しておいて見れるようにしておくとベストです.(なお,当方のサーバを使用して実装してあげることも可ですのでご相談願います)

HOME へ戻る



提供:北海道電力ネットワーク㈱ 北海道電気管理技術者協会 札-459号
長谷川電気管理事務所(長谷川博)