Asteriskで電話が切れた後に処理をしたい(その2)

Asteriskで電話が切れた後に処理をしたい

ベースとなるのはAsteriskからのLチカ制御だ

Interface 2016年3月号の記事を読んで判ったことは、Raspberry PiのGPIOを制御するプログラムを組み、それをAGIスクリプトとして実行させることでAsteriskからGPIOを制御することが可能となること、記事ではASterisk経由の内線番号を使ってLEDの点灯と消灯を制御している。どうして点灯と消灯を別々のスクリプトにしてあるのかは不明であったが、これで長年のリレーを制御する方法の具体的な部分が明らかになった。

AGIをテストする

早速使っていないRaspberry PiにAsterisk13.13.0をインストールしてのテスト環境を整え、内線用ip電話機2台をつなぎ内線間の通話ができることを確認した(内線番号は201と202を利用:voip-info.jp提供のAsterisk13サンプル設定ファイルの定義をそのまま利用しました)。

これとは別にRaspberry Piと接続する配線用のブレッドボードとLEDと1KΩの抵抗を用意して配線を行った。

配線図は記事にでているのと同じ直列配線として、Raspberry Piの+3V(Pin1番)から抵抗とLEDを直列につないで最後にLEDの短い方の足にGPIO4(Pin7番)からのケーブルを接続した。

Asteriskの定義の定義ファイルはhttp://www.voip-info.jp/index.php/Asterisk_13_サンプル設定ファイル/で提供されているものを使っています。

/etc/asterisk/asterisk.confを参照すると以下の内容が見られます。

 

 

[directories]
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk
astagidir => /var/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run
astlogdir => /var/log/asterisk

astagidir(5行目)にAGIスクリプトを保存する場所があるので確認します。

次に以下の処理をするAGIスクリプトをこのホルダの中に保存します。

LEDを消すスクリプト
スクリプト名はagi_led_OFF.agi

#!/bin/sh
echo "ANSWER"
sleep 2
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction
echo "1" > /sys/class/gpio/gpio4/value
sleep 5

LEDを点けるスクリプト
スクリプト名はagi_led_ON.agi

#!/bin/sh
echo "ANSWER"
sleep 1
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction
echo "0" > /sys/class/gpio/gpio4/value
sleep 1

続いて/etc/asterisk/extensions.confを開いてAGIの動作用スクリプトを内線番号に割り当てる処理を追加する。
ここはInterface2016年3月号の記事と同じ内線番号に割り当てることとする。

内線:390はLEDを消す
内線:391はLEDを点ける

    前略

;300番台は特番で機能に割り当てています
;音声会議
exten => 301,1,NoOp(音声会議)
exten => 301,n,Answer()
exten => 301,n,Confbridge(${EXTEN})
exten => 301,n,Hangup

;LEDの消灯 内線390
exten => 390,1,AGI(agi_led_OFF.agi)

;LEDの点灯 内膳391
exten => 391,1,AGI(agi_led_ON.agi)

    後略

以上でextensions.confの定義ができたのでAsteriskを再起動させる(rebootでも良いし、sudo service asterisk restartのコマンドでも良い)。

このあと、コンソール画面(sshで接続している画面)で以下のコマンドを使ってagiのデバッグモードに入っておく。
1行目のvの数は適当でよい
10行目がagiのデバッグモードを指定

[email protected]:/etc/asterisk $ sudo asterisk -vvvvvvvvvvvvvvvvvvvr
Asterisk 13.13.0, Copyright (C) 1999 - 2014, Digium, Inc. and others.
Created by Mark Spencer <[email protected]>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 13.13.0 currently running on raspberrypi (pid = 2302)
raspberrypi*CLI>agi set debug on
AGI Debugging Enabled
raspberrypi*CLI>

早速、内線電話機202から391に電話をするとコンソール画面は以下のような画面が表示され、通話開始約4秒後にLEDが赤く点灯した。
かなり感動する

raspberrypi*CLI>agi set debug on
AGI Debugging Enabled
raspberrypi*CLI>
  == Using SIP RTP CoS mark 5
    -- Executing [[email protected]:1] AGI("SIP/202-00000000", "agi_led_ON.agi") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/agi_led_ON.agi
<SIP/202-00000000>AGI Tx >> agi_request: agi_led_ON.agi
<SIP/202-00000000>AGI Tx >> agi_channel: SIP/202-00000000
<SIP/202-00000000>AGI Tx >> agi_language: ja
<SIP/202-00000000>AGI Tx >> agi_type: SIP
<SIP/202-00000000>AGI Tx >> agi_uniqueid: 1481112646.0
<SIP/202-00000000>AGI Tx >> agi_version: 13.13.0
<SIP/202-00000000>AGI Tx >> agi_callerid: 202
<SIP/202-00000000>AGI Tx >> agi_calleridname: 202
<SIP/202-00000000>AGI Tx >> agi_callingpres: 0
<SIP/202-00000000>AGI Tx >> agi_callingani2: 0
<SIP/202-00000000>AGI Tx >> agi_callington: 0
<SIP/202-00000000>AGI Tx >> agi_callingtns: 0
<SIP/202-00000000>AGI Tx >> agi_dnid: 391
<SIP/202-00000000>AGI Tx >> agi_rdnis: unknown
<SIP/202-00000000>AGI Tx >> agi_context: default
<SIP/202-00000000>AGI Tx >> agi_extension: 391
<SIP/202-00000000>AGI Tx >> agi_priority: 1
<SIP/202-00000000>AGI Tx >> agi_enhanced: 0.0
<SIP/202-00000000>AGI Tx >> agi_accountcode:
<SIP/202-00000000>AGI Tx >> agi_threadid: 1980511264
<SIP/202-00000000>AGI Tx >>
<SIP/202-00000000>AGI Rx << ANSWER > 0x76105f50 -- Probation passed - setting RTP source address to 192.168.11.9:5004
<SIP/202-00000000>AGI Tx >> 200 result=0
    -- <SIP/202-00000000>AGI Script agi_led_ON.agi completed, returning 0
    -- Auto fallthrough, channel 'SIP/202-00000000' status is 'UNKNOWN'
[Dec  7 21:10:48] ERROR[5057]: cdr_custom.c:174 custom_log: Unable to re-open master file /var/log/asterisk/cdr-custom/Master.csv : No such file or directory
[Dec  7 21:10:48] ERROR[5057]: cdr_csv.c:315 csv_log: Unable to re-open master file /var/log/asterisk//cdr-csv//Master.csv : No such file or directory
raspberrypi*CLI>

なんだかのERRORがでているがテスト環境だから細かいことは気にしない。

内線番号391はLEDを消す機能は付いていないので、再び内線番号390に電話をする。そうすると約4秒後にLEDが消灯する。
すんげぇ感動
この時もコンソールには以下の内容が表示される。

  == Using SIP RTP CoS mark 5
    -- Executing [3[email protected]:1] AGI("SIP/202-00000001", "agi_led_OFF.agi") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/agi_led_OFF.agi
<SIP/202-00000001>AGI Tx >> agi_request: agi_led_OFF.agi
<SIP/202-00000001>AGI Tx >> agi_channel: SIP/202-00000001
<SIP/202-00000001>AGI Tx >> agi_language: ja
<SIP/202-00000001>AGI Tx >> agi_type: SIP
<SIP/202-00000001>AGI Tx >> agi_uniqueid: 1481112742.2
<SIP/202-00000001>AGI Tx >> agi_version: 13.13.0
<SIP/202-00000001>AGI Tx >> agi_callerid: 202
<SIP/202-00000001>AGI Tx >> agi_calleridname: 202
<SIP/202-00000001>AGI Tx >> agi_callingpres: 0
<SIP/202-00000001>AGI Tx >> agi_callingani2: 0
<SIP/202-00000001>AGI Tx >> agi_callington: 0
<SIP/202-00000001>AGI Tx >> agi_callingtns: 0
<SIP/202-00000001>AGI Tx >> agi_dnid: 390
<SIP/202-00000001>AGI Tx >> agi_rdnis: unknown
<SIP/202-00000001>AGI Tx >> agi_context: default
<SIP/202-00000001>AGI Tx >> agi_extension: 390
<SIP/202-00000001>AGI Tx >> agi_priority: 1
<SIP/202-00000001>AGI Tx >> agi_enhanced: 0.0
<SIP/202-00000001>AGI Tx >> agi_accountcode:
<SIP/202-00000001>AGI Tx >> agi_threadid: 1982116896
<SIP/202-00000001>AGI Tx >>
<SIP/202-00000001>AGI Rx << ANSWER > 0x76105f50 -- Probation passed - setting RTP source address to 192.168.11.9:5004
<SIP/202-00000001>AGI Tx >> 200 result=0
    -- <SIP/202-00000001>AGI Script agi_led_OFF.agi completed, returning 4
  == Spawn extension (default, 390, 1) exited non-zero on 'SIP/202-00000001'
[Dec  7 21:12:29] ERROR[5057]: cdr_custom.c:174 custom_log: Unable to re-open master file /var/log/asterisk/cdr-custom/Master.csv : No such file or directory
[Dec  7 21:12:29] ERROR[5057]: cdr_csv.c:315 csv_log: Unable to re-open master file /var/log/asterisk//cdr-csv//Master.csv : No such file or directory

なんだかのERRORがでているがテスト環境だから細かいことは気にしない。

着信したらLEDを点灯させ、切ったらLEDを消灯させる

次のテストは内線番号に着信したらLEDを点灯させて、受話器を切ったらLEDを消すこと。
これができれば念願の切った後にソレノイドのスイッチを入れて切ることに近づきます。

AGIスクリプトはそのまま使えば良いので、/etc/asterisk/extensions.confの内線電話の呼び出し部分に着目します。

;内線呼び出し
exten => _20Z,1,NoOp(内線呼出)
exten => _20Z,n,Dial(SIP/${EXTEN},60)
exten => _20Z,n,Hangup

これを次のようにagiスクリプト処理を追加してみました。

;内線呼び出し
exten => _20Z,1,NoOp(内線呼出)
exten => _20Z,1,agi(agi_led_ON.agi)
exten => _20Z,n,Dial(SIP/${EXTEN},60)
exten => _20Z,n,agi(agi_led_OFF.agi)
exten => _20Z,n,Hangup

私の頭の中では、着信するとagiのLED点灯処理が実行されそのあとに内線電話を鳴動、受話器を切ったら、aigのLED消灯処理が実行される。
なんだ簡単じゃん。
と思って内線201から200の呼び出しを行う、LED点灯、鳴動、受話器を取る、受話器を置く、LED点灯しっぱなし!
しょうが無いので内線202から内線390に発信してLEDを消灯しました。

何故できないのだろうか?を考えた回答が、電話を切った後、つまりHangupした後の処理だからLED消灯のagi処理位置が違うのではないか?ということで次のようにextensions.confの定義を変更しました。

;内線呼び出し
exten => _20Z,1,NoOp(内線呼出)
exten => _20Z,1,agi(agi_led_ON.agi)
exten => _20Z,n,Dial(SIP/${EXTEN},60)
exten => _20Z,n,Hangup
exten => _20Z,n,agi(agi_led_OFF.agi)

結局のところダメ!
この後何度テストしても結局LEDの消灯は内線390に発信する以外できませんでした。

なぜ思っているように動作しないのだろう?と言う疑問の中extensions.confを次のように設定しなおしてテストを実行してみました。
期待としては、着信するとLEDを数秒点灯させた後に消灯させ、その後鳴動させるという動作です。

;内線呼び出し
exten => _20Z,1,NoOp(内線呼出)
exten => _20Z,n,AGI(agi_led_ON.agi)
exten => _20Z,n,AGI(agi_led_OFF.agi)
exten => _20Z,n,Dial(SIP/${EXTEN},60)
exten => _20Z,n,Hangup

期待は裏切りません。数秒点灯した後に消灯、それから内線電話のベルは鳴りました。

結局、AGIを使った場合には、exten => _20Z,n,Dial(SIP/${EXTEN},60)の行以降のどこにセットしても電話を切ったが最後、agiスクリプトの処理をすることはできませんでした。
「電話を切った後の処理はどうでもいいのだから、知らないよそんなこと」という開発側の意図があるのではないかと思ってしまいました。

AGIを使って実際にしたいこと

私が実際にしたいことは電話を切った後に、LEDを点灯させた後にLEDを消灯すること。これができないとプッシュ型ソレノイドを使って切るボタンを押すことはできません。
内線201から内線200に電話をする。鳴動、受話器を取る、切る。実験失敗。LEDを消すために内線390に電話をする。という繰り返しとなってしまいました。

ここで切るボタンを押す処理は行き詰ってしまいました。
また、一から調べ直さなければならないようです。

長くなったのでここでいったん終了。次に続きます。