pusuke0418’s diary

異常にマルチタスクな社内SEのブログ

ネットワークスイッチコンフィグジェネレート

知り合いとスイッチのコンフィグ作りとかその確認てめんどくさいよね、そうですね、というような話になり、スクリプトとかかね、といっても、いちいちスクリプトのファイルに設定値書き込むのかね、とかライブラリ覚えたりとかスクリプト勉強したくないよね、ということに。

そして、そのとき話に出たのは、絶対に設定値パラメータシート埋めてから設定コンフィグ作って、流し込んでやってるけど、毎回繰り返しだよね、単純ゆえにミスるよねと。まぁ、そこが楽になれば難しいことや凝ったことしなくて良いよね、と。

じゃぁ、Excelで作ってるパラメータシートで毎回同じような設定入れるところをそのままExcel上でジェネレートすれば良いじゃないという方向。

例えば、下記のようなものは単純。ホスト名の設定

A B
1 項目
2 hostname L3SW-01

下記のように文字列をつなげるだけ。ここでは便宜的にC列に式を、D列に結果を書いています。

A B C D
2 hostname L3SW-01 =B5&" "&C5 hostname L3SW-01



では、条件分岐が出る部分はどうするのか、という話になります。例えば、インタフェース設定。モードがaccessかtrunkかで、関連して必要となるコマンドが変わってくる。特にciscoを意図しているわけではないけれども、例えば下記のようなスイッチに関する設定表だったとする。

A B C D
1 インタフェース 番号 タイプ VLAN
2 fastethernet 0/0 access 100
3 fastethernet 0/1 trunk 100,200,300
4 fastethernet 0/2 150

IFの分岐と、COUNTIFによる文字列の確認を利用する。長くなるので下に記します。上記の表でいうと、2行目のfa0/0のところに対応しています。これをひとつのセルの中に記述。

="interface "&A2&" "&B2&CHAR(10)&
IF(COUNTIF(C2,"access")," switchport mode access"&CHAR(10)&"switchport access vlan "&D2,
IF(COUNTIF(C2,"trunk")," switchport trunk encapsulation dot1q"&CHAR(10)&" 
switchport mode trunk"&CHAR(10)
&" switchport trunk allowed vlan "&D2,"
"インタフェースタイプ指定しましょう"))

ぐちゃぐちゃに見えるけれども、単にIF関数と、COUNTIF関数を使っている(もし指定のセルにaccessという文字があれば○○、accessが無く、trunkという文字があれば△△)。ところどころにはさまっているCHAR(10)というのは、改行コードで、同一セル内で改行させることができる。結果は、下記のようになる。例えば、先ほどのインタフェース表中、E列の最初の行にだけ書いて、あとはセルのはしっこをドラッグして下のほうのセルまでオートフィルすれば良いです。

E
interface fastethernet 0/0
switchport mode access
switchport access vlan 100"
interface fastethernet 0/1
switchport trunk encapsulation dot1q
switchport mode trunk
switchport trunk allowed vlan 100,200,300
interface fastethernet 0/2
インタフェースタイプ指定しましょう

ただし、ここで使っている式では、出力にセル内改行を含んでいるため、実際生成されたコマンドであるセルの内容を、例えばテキストエディタにでもコピペすると、下記のようにダブルクォテーションを含んでペーストされてしまう。

"interface fastethernet 0/0
 switchport mode access
 switchport access vlan 100"

Excelでのダブルクォテーションの発生を避けるためには、あらかじめ1セル1行のコマンドとするか、あるいは割り切ってテキストエディタにコピペした後一括でダブルクォテーションを削る。

作業テンプレ化しておけば、Aという設定にBという別機能の設定が必須だが忘れてしまった、ということも避けやすい、かも

Juliusの起動エラーに関するメモ

音声認識ができるJuliusをRaspberry Piにて使いたい。Juliusをインストールして、起動させようとすると下記のようなログが出て起動しない。インストールは、単純に./configure→make→sudo make installにて実施。

Stat: adin_oss: device name = /dev/dsp (application default)
Error: adin_oss: failed to open /dev/dsp
failed to begin input stream

何となく、juliusは/dev/dspを期待しているが、それが開けないということに見える。

ログで検索すると、下記を行えば良いという情報がしばしば見当たる。snd-pcm-ossなるモジュールをロードすればよい。

$ sudo modprobe snd-pcm-oss

そして、再度Juliusを起動すると、しかし、上記のエラーは再び出る。

よくよく見てみると/dev/dspはたしかにモジュールロードによって出現したが、他に/dev/dsp1と/dev/dsp2ができていた。

そして、次のサイトORBIT SPACEに有益な情報を発見。引用をさせていただきます。「USBマイクを接続するとJuliusが標準で使用されるデバイスファイル(/dev/dsp)とは異なるため環境変数で指定します」とのことで、「AUDIODEV=/dev/dsp1」の環境変数を設定されている。手元の環境では、USBのスピーカとマイクがささっていて、マイクを抜き差しして確認してみると、そのときはdsp, dsp2がスピーカ、dsp1がおそらくマイクのようだった。なので手元の環境でもAUDIODEV=/dev/dsp1を設定したところ、動作。

あとは起動時に上記を読み込むようにするのと、dsp番号は手元の環境であると、ときに認識順によって変わってしまうかなと、いった点をもう少し調査。

[環境]
Raspberry Pi 2 Model B

$ uname -r
3.18.11-v7+

jurlius-4.3.1

Raspberry Piで雨降ってたらLED点滅させる

マンションの、家の中から雨の状況が確認しづらく、廊下からもわからなく、下までエレベータで降りたら雨が降ってたということが多かったです。

そんな中、RaspberryPiとYahoo!気象情報APIを使った雨量確認ガジェットを作ってみた | 株式会社バニーホップという情報がありました。

Raspberry PiとYahooのAPIを利用して近傍の雨量情報を取得し、雨量に応じてLEDを光らせるというもののようです。Yahooの利用方法からステップバイステップで紹介されていて、とてもわかりやすい。

そこではnode.jsとフルカラーLEDが利用されていましたが、倣って私は、pythonで単色LEDで作ってみました。まずは動いたので下記しました。

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

import sys
import urllib
import json
import time
import RPi.GPIO as GPIO
import math
import datetime
import os

#ピンをセット。16番を利用。明るさ調整にPWMを利用
#pi(16番ピン)----抵抗-----LED-----pi(GND)の接続
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.OUT)
p = GPIO.PWM(16, 120)
p.start(0)

while True:
   url = "http://weather.olp.yahooapis.jp/v1/place?"
   appid = "myappid"
   params = urllib.urlencode({"appid" : appid, "coordinates" : "経度,緯度", "output" : "json",})
   
  #データを取得、雨量の部分のみをrainfallに格納
   response = urllib.urlopen(url + params)
   f = response.read()
   jsondata = json.loads(f)
   rainfall = jsondata["Feature"][0]["Property"]["WeatherList"]["Weather"][0]["Rainfall"]

   #取得した値をファイルに書き込み(log取得的な)
   d = datetime.datetime.today()
   today = d.strftime("%Y%m%d")
   f = open("/home/pi/log/"+today+"_rain.txt", "ab")   
   f.write(str(datetime.datetime.now()) + "," + str(rainfall) + "\n")
   f.close()

   #雨が降っていればLED点滅
   if rainfall <= 0:
       time.sleep(180)
   else:
       for i in range(1,90):
          for dc in range(0, 30, 3):
             p.ChangeDutyCycle(dc)
             time.sleep(0.1)
          for dc in range(30, 0, -3):
             p.ChangeDutyCycle(dc)
             time.sleep(0.1)

だいたい3分おきくらいで取れるだろうというアバウトなものです。

で、狙いとしては雨が降っていればLED点滅の部分で、取得雨量に応じて明るさと変化の間隔を分岐で変えれば雨量もなんとなくわかるかも、というものがあります。それに応じてループ回数とPWMの動作を変えればよいかなと思ってますが、雨降ってるのがわかれば良いのでこのままになりそうです

テスト動作させてうまくいってそうであったので、supervisorに登録してデーモン化しておきました。ここは参考ページだと、pm2にあたる部分かな?