スポンサーサイト

0

    一定期間更新がないため広告を表示しています

    • 2019.03.16 Saturday
    • -
    • -
    • -
    • by スポンサードリンク

    raspberryPIでWEBからの指令でルーターにコマンドを送るシステム

    0

      前のraspberryPI関連の記事でsshでログインしてパイプを使って制御コマンドの送受信を行う部分を作成しました。
      今回はそれをWEBから制御する部分を書きます。
      前の記事は
       http://miha.jugem.cc/?eid=127

      今回のはちょっと難しい。
      肝になるのは前回作ったraspberryPiからルーターを制御して結果を取得する部分なんだけど、
      それと、ずっと前に作った
      WEB画面からの制御で100Vの電灯をON/OFFする記事
       http://miha.jugem.cc/?eid=105
      のWEB制御による遠隔システムを組み合わせる。

      システム構成

      システム構成

      このシステムの利点はraspberryPiを相手先のプライベートネットワークへ置かせてもらう事によって、
      ちょっと難しいルーター設定を拠点へ行かなくても遠隔でメンテナンスが可能になる事です。
      拠点にインターネットに接続できる環境さえあれば実施可能でハードルは低いように思えます。

      プログラムの一覧と簡単な解説
      構成図の右上から順番に行きます。
      拡張子.cgiはperlのプログラムです。ちなみに環境はMicrosoftAzureです。
      現時点でazureは標準ではperlをサポートしていませんが、
      perlの環境構築する記事は他にもありますが、
      自分なりに噛み砕いた記事をそのうち書きます。
      以下ではルーターと表現していますが、基本的にsshまたはtelnetでログイン可能なものは制御可能です。

      -1.edit.cgi
       ルーターのコマンドを登録する画面です。
       ルーターコマンドのだけでは制御が難しくてコマンド体系は以下の感じになっている
       コマンドは6種類でコロンを含めて7桁の英字です。
        ID  : ルーターにログインする為のユーザIDを指定
        PASS: ルーターにログインする為のパスワードを指定
        TEL : telnetでルーターにログイン
        SSH : sshでルーターにログイン
        TIME: WAITコマンドで何秒まで待つかを指定する
        WAIT: ルーターからの応答を待つ。指定した文字列が来るか、WAITで指定した時間経過するまで待つ
        SEND: ルーターへ送信するコマンド
       上記のコマンドを組み合わせたテキストを入力してOKをクリックする。

      -2.touroku.cgi
       edit.cgiから呼び出されて渡されたテキストの情報をサーバーに書き込む
      き.req.cgi
       raspberryPi側から呼び出されるCGIです
       最後にtouroku.cgiで書き込まれたテキストを返します。
      ΝЛweb-client-req-exec-result.c
       raspberryPiの中で動くプログラムです。c言語です。
       req.cgiで取得したコマンドをルーターに送信したり、一定時間待ったり、ルーターからの応答をWebサーバーへ送るプログラムです。
       結果をWebサーバーへ送る部分はresult.cgiを呼び出す。
      result.cgi
       raspberryPiから送信された結果をWebサーバーに書き込む
      control.cgi
       指示を出されたら一定間隔で呼び出される。というか自身でreloadしている。
       サーバーから最後の電文が来るとreloadは停止する。

      という感じで動きます。

      実際に動いているところ

      今回送信したコマンドはこちら。
       TIME:10
       ID  :none
       PASS:P@ssw0rd
       TEL :192.168.33.241
       TIME:30
       WAIT:c1812J>
       SEND:enable
       WAIT:assword:
       SEND:P@ssw0rd
       WAIT:c1812J#
       SEND:terminal length 0
       WAIT:c1812J#
       SEND:show run
       WAIT:c1812J#
       SEND:show ip interface brief
       WAIT:c1812J#
       SEND:configure  terminal
       WAIT:c1812J#
       SEND:interface FastEthernet1
       WAIT:c1812J(config-if)#
       SEND:ip address 192.168.20.254 255.255.255.0
       WAIT:c1812J(config-if)#
       SEND:no shutdown
       WAIT:c1812J(config-if)#
       SEND:end
       WAIT:c1812J#
       SEND:show ip interface brief
       WAIT:c1812J#
       SEND:exit
       TIME:3
       WAIT:%
      ciscoの1812Jに対してコマンドを送信します。
      実際のコマンド設定部分は
       「ip address 192.168.20.254 255.255.255.0」と「no shutdown」の所で、
       一回目の「show ip interface brief」でadministratively downになっていたFastEthernet0が
       二回目の「show ip interface brief」ではStatusがUPになってIPアドレスが設定されています。

      NW機器たち。上がYAMAHAのRTX1100。下がciscoの1812J
      ルーターやNW機器


      それとraspberryPI3
      raspberryPi3

      raspberryPIの所は前に公開した肝の部分にwebアクセスを追加したものなのでWebサーバー部分のプログラムを以下に掲載しておきます。
      ■■■■■■■■■■■
      ■edit.cgi
      ■■■■■■■■■■■
      use CGI;
      my $q = new CGI;
      $para1 = $q->param('para1');

      # HTML出力
      print "Content-type: text/html¥n¥n";
      print "<html>¥n";
      print "<head>¥n";
      print " <META http-equiv=Control content=no-cache>¥n";
      print " <META http-equiv=Pragma content=no-cache>¥n";
      print " <META http-equiv=Content-type content='text/html; charset=Shift_JIS'>¥n";
      print "<title>AgentSystem 編集</title>¥n";
      print "</head>¥n";
      print "<body>¥n";

      LockON();
      print("<hr>");
      print("<font size=+10>AgentSystem</font>");
      print("<hr>");
      print("編集<br>");
      print("<hr>");

      if(!open(request_file, "agent/request.dat")){
       EmergencyStop(1000);
      }

      print ("<form method=post action=touroku.cgi>");
      print (" <textarea name=set cols=40 rows=20>");
      while($InRec=<request_file>){
       $a = substr ($InRec , 0 , 5 );
       if($a eq "REQ :"){
        ;
       }
       else{
        print("$InRec");
       }
      }
      print (" </textarea>");
      print (" <input type=submit value=OK>");
      print ("</form>");
      close(request_file);


      LockOFF();

      # HTML出力
      print "</body>¥n";
      print "</html>¥n";

      exit;

      sub LockON
      {
       if(!open(LOCK, "> agent/LOCK")){
        EmergencyStop(1000);
       }
       flock(LOCK, 2);      
      }

      sub LockOFF
      {
       close(LOCK);
      }

      sub EmergencyStop
      {
       $line = $_[0];
       $Status = $_[0];
       
       if( $Status eq "0" ){
        
       }
       print "EmergencyStop($line)";
       
       exit( -1 );
      }

      sub SpaceCut
      {
       local($String) = @_;

       $String =~ s/ //g; #// 全角空白を削除
       $String =~ s/ //g; #// 半角空白を削除
       $String =~ s/¥n//g; #// enterを削除

       return ($String);
      }

      ■■■■■■■■■■■
      ■touroku.cgi
      ■■■■■■■■■■■
      use CGI;
      my $q = new CGI;
      $set = $q->param('set');

      # HTML出力
      print "Content-type: text/html¥n¥n";
      print "<html>¥n";
      print "<head>¥n";
      print " <META http-equiv=Control content=no-cache>¥n";
      print " <META http-equiv=Pragma content=no-cache>¥n";
      print " <META http-equiv=Content-type content='text/html; charset=Shift_JIS'>¥n";
      print " <meta http-equiv=refresh content='3 ; URL=control.cgi'>¥n";
      print "<title>AgentSystem 登録完了</title>¥n";
      print "</head>¥n";
      print "<body>¥n";

      LockON();

      print("<hr>");
      print("<font size=+10>AgentSystem</font>");
      print("<hr>");
      print("登録<br>");
      print("<hr>");

      ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
      my $yyyymmddhhmmss = sprintf("%04d%02d%02d%02d%02d%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec);
      print ("REQ :$yyyymmddhhmmss<br>¥n");
      print ("<a href=control.cgi>戻る</a><br>¥n");

      if(!open(request, "> agent/request.dat")){
       EmergencyStop(1000);
      }

      print request "REQ :$yyyymmddhhmmss¥n";
      print request "$set";
      close(request);

      #resultファイルを初期化
      if(!open(result, "> agent/result.dat")){
       EmergencyStop(1000);
      }
      close(result);
      #doneファイルを初期化
      if(!open(done, "> agent/done.dat")){
       EmergencyStop(1000);
      }
      close(done);

      LockOFF();

      # HTML出力
      print "</body>¥n";
      print "</html>¥n";

      exit;

      sub LockON
      {
       if(!open(LOCK, "> agent/LOCK")){
        EmergencyStop(1000);
       }
       flock(LOCK, 2);      
      }

      sub LockOFF
      {
       close(LOCK);
      }

      sub EmergencyStop
      {
       $line = $_[0];
       $Status = $_[0];
       
       if( $Status eq "0" ){
        
       }
       print "EmergencyStop($line)";
       
       exit( -1 );
      }

      sub SpaceCut
      {
       local($String) = @_;

       $String =~ s/ //g; #// 全角空白を削除
       $String =~ s/ //g; #// 半角空白を削除
       $String =~ s/¥n//g; #// enterを削除

       return ($String);
      }

      ■■■■■■■■■■■
      ■req.cgi
      ■■■■■■■■■■■
      use CGI;
      my $q = new CGI;

      # HTML出力
      print "Content-type: text/plain¥n¥n";

      LockON();
      if(!open(request_file, "agent/request.dat")){
       EmergencyStop(1000);
      }
      while($InRec=<request_file>){
       print $InRec
      }
      close(request_file);

      if(!open(agent, "> agent/agent.dat")){
       EmergencyStop(1000);
      }

      @youbi = ('日', '月', '火', '水', '木', '金', '土');
      ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
      $year += 1900;
      $mon += 1;
      print agent "$year年$mon月$mday日($youbi[$wday]) $hour時$min分$sec秒¥n";
      close(agent);

      LockOFF();

      exit;

      sub LockON
      {
       if(!open(LOCK, "> agent/LOCK")){
        EmergencyStop(1000);
       }
       flock(LOCK, 2);      
      }

      sub LockOFF
      {
       close(LOCK);
      }

      sub SpaceCut
      {
       local($String) = @_;

       $String =~ s/ //g; #// 全角空白を削除
       $String =~ s/ //g; #// 半角空白を削除
       $String =~ s/¥n//g; #// enterを削除

       return ($String);
      }

      sub EmergencyStop
      {
       $line = $_[0];
       $Status = $_[0];
       
       if( $Status eq "0" ){
        
       }
       print "EmergencyStop($line)";
       
      }

      ■■■■■■■■■■■
      ■result.cgi
      ■■■■■■■■■■■
      use CGI;
      my $q = new CGI;

      $argc = $q->param('argc');
      $upload_flag = $q->param('flag');

      # HTML出力
      print "Content-type: text/plain¥n¥n";
      LockON();

      if($upload_flag eq "0"){
       if(!open(result, "> agent/result.dat")){
        EmergencyStop(1000);
       }
      }
      else{
       if(!open(result, ">> agent/result.dat")){
        EmergencyStop(1000);
       }
      }

      print "argc=$argc¥n";
      for ($count = 0; $count < $argc; $count++){
       $key = $count;
       my $read_line = $q->param("$key");
       print result "$read_line¥n";
       print "key=$key:read_line=$read_line¥n";
      }
      close(result);
      #
      if(!open(done, "> agent/done.dat")){
       EmergencyStop(1000);
      }
      if($upload_flag eq 0){
       print done "RUNNING...";
      }
      if($upload_flag eq 1){
       print done "RUNNING...";
      }
      if($upload_flag eq 2){
       print done "...DONE";
      }
      close(done);

      LockOFF();

      exit;

      sub LockON
      {
       if(!open(LOCK, "> agent/LOCK")){
        EmergencyStop(1000);
       }
       flock(LOCK, 2);      
      }

      sub LockOFF
      {
       close(LOCK);
      }

      sub EmergencyStop
      {
       $line = $_[0];
       $Status = $_[0];
       
       if( $Status eq "0" ){
        
       }
       print "EmergencyStop($line)";
       
       exit( -1 );
      }

      sub SpaceCut
      {
       local($String) = @_;

       $String =~ s/ //g; #// 全角空白を削除
       $String =~ s/ //g; #// 半角空白を削除
       $String =~ s/¥n//g; #// enterを削除

       return ($String);
      }

      ■■■■■■■■■■■
      ■control.cgi
      ■■■■■■■■■■■
      use CGI;
      my $q = new CGI;
      $para1 = $q->param('para1');

      if(!open(done_file, "agent/done.dat")){
       EmergencyStop(1000);
      }
      $DoneStr=<done_file>;
      close(done_file);

      # HTML出力
      print "Content-type: text/html¥n¥n";
      print "<html>¥n";
      print "<head>¥n";
      print " <META http-equiv=Control content=no-cache>¥n";
      print " <META http-equiv=Pragma content=no-cache>¥n";
      print " <META http-equiv=Content-type content='text/html; charset=Shift_JIS'>¥n";
      if( $DoneStr ne "...DONE" ){
       print " <meta http-equiv=Refresh content=5>¥n";
      }
      print "<title>AgentSystem</title>¥n";
      print "</head>¥n";
      print "<body>¥n";

      print("<hr>");
      print("<font size=+10>AgentSystem</font>");
      print("  <a href='edit.cgi'>編集</a>");
      print("<hr>");
      print("要求<br>");
      print("<hr>");

      LockON();
      if(!open(request_file, "agent/request.dat")){
       EmergencyStop(1000);
      }
      while($InRec=<request_file>){
       print $InRec;
       print("<br>");
      }
      close(request_file);

      printf("<hr>");
      print("結果<br>");
      printf("<hr>");
      printf("<xmp>");
      if(!open(request_file, "agent/result.dat")){
       EmergencyStop(1000);
      }
      while($InRec=<request_file>){
       print $InRec;
      }
      close(request_file);
      print $DoneStr;

      printf("</xmp>");
      printf("<hr>");
      print("Agent最終アクセス時間<br>");
      printf("<hr>");
      if(!open(agent_file, "agent/agent.dat")){
       EmergencyStop(1000);
      }
      while($InRec=<agent_file>){
       print $InRec;
      }
      close(agent_file);
      printf("<hr>");
      print("<a href='edit.cgi'>編集</a>");
      printf("<hr>");


      LockOFF();

      # HTML出力
      print "</body>¥n";
      print "</html>¥n";

      exit;

      sub LockON
      {
       if(!open(LOCK, "> agent/LOCK")){
        EmergencyStop(1000);
       }
       flock(LOCK, 2);      
      }

      sub LockOFF
      {
       close(LOCK);
      }

      sub EmergencyStop
      {
       $line = $_[0];
       $Status = $_[0];
       
       if( $Status eq "0" ){
        
       }
       print "EmergencyStop($line)";
       
       exit( -1 );
      }

      sub SpaceCut
      {
       local($String) = @_;

       $String =~ s/ //g; #// 全角空白を削除
       $String =~ s/ //g; #// 半角空白を削除
       $String =~ s/¥n//g; #// enterを削除

       return ($String);
      }


      スポンサーサイト

      0
        • 2019.03.16 Saturday
        • -
        • 12:41
        • -
        • -
        • by スポンサードリンク


        PR

        calendar

        S M T W T F S
         123456
        78910111213
        14151617181920
        21222324252627
        28293031   
        << July 2019 >>

        selected entries

        categories

        archives

        recent comment

        recent trackback

        profile

        search this site.

        others

        mobile

        qrcode

        powered

        無料ブログ作成サービス JUGEM