MMDAgentに天気予報を教えてもらう

MMDAgentは標準では決められた設定に沿って応答するだけで、動的に応答を変化させることができません。

ここでは.fstファイルの再読み込みプラグインと、AutoHotkeyを活用してMMDAgentに天気予報を教えてもらう(やや邪道な)方法を紹介します。

MMDAgentのシナリオ設定

「.fst」の設定は以下のとおりです。「# tenki_yoho start」から「# tenki_yoho end」までの内容は.ahk経由で起動するRubyスクリプトにより動的に書き換えます。

1 201 RECOG_EVENT_STOP|天気予報 SYNTH_START|mei|mei_voice_normal|少々お待ちください。
201 2 SYNTH_EVENT_STOP|mei EXECUTE|C:\path\to\tenki_yoho.ahk
# tenki_yoho start
1 211 KEY|t SYNTH_START|mei|mei_voice_normal|明日の天気は晴れです。
211 2 SYNTH_EVENT_STOP|mei <eps>
# tenki_yoho end
1 251 KEY|e SYNTH_START|mei|mei_voice_normal|天気予報の取得に失敗しました。
251 2 SYNTH_EVENT_STOP|mei <eps>

tenki_yoho.ahk

AutoHotkeyではまず天気予報を取得しMMDAgentの.fstを書き換えるためのRubyスクリプトを起動します。

Rubyスクリプトの終了コードによって、MMDAgentに送るキーを切り替えています。正常時はrキーで設定を再読み込みした後、tキーで天気を読み上げます。

RunWait, ruby tenki_yoho.rb, C:\path\to\working_dir, min
if (ErrorLevel <> 0) {
    WinActivate, ahk_class MMDAgent
    WinWaitActive, ahk_class MMDAgent, , 2
    Send, e
} else {
    WinActivate, ahk_class MMDAgent
    WinWaitActive, ahk_class MMDAgent, , 2
    Send, r
    Sleep, 500
    Send, t
}

tenki_yoho.rb

天気予報の取得にはruby-weatherhacksを使わせてもらいました。Ruby1.9ではコード内の日本語がエラーになってしまうため、lib/ruby/gems内のforecastmap.rbをUTF-8で再保存したうえマジックコメントを追加して無理やり対応しています。

# coding: utf-8
require "weatherhacks"
require "kconv"

Encoding.default_external = 'Shift_JIS'

begin
  forecast = WeatherHacks.lwws("東京", :tomorrow)

  FST_TEXT = &lt;&lt;EOS
# tenki_yoho start
1 211 KEY|t SYNTH_START|mei|mei_voice_normal|明日の天気は#{forecast.telop}です。
211 2 SYNTH_EVENT_STOP|mei <eps>
# tenki_yoho end
EOS

  f = File.open("path/to/MMDAgent_Example.fst")
  content = f.read().gsub(/# tenki_yoho start.*# tenki_yoho end\n/m, FST_TEXT.tosjis)
  File.open("path/to/MMDAgent_Example.fst", 'w') { |file| file.write(content) }
rescue
  exit 1
end

ただしweatherhacksライブラリで温度の情報が正しく取得できなかったり、livedoorのWeather Hacks自体がtomorrowで指定しても時間によっては当日の天気を返してきたり(?)と微妙なので、この内容は改善の余地があります。

おわりに

元々はAutoHotkeyでMMDAgent自体を再起動して設定ファイルを読み込ませようと考えていましたが、設定ファイルを再読み込みできる素敵なプラグインがあったので使わせて頂きました。

同じような方法で、ニュースや株価情報を読み上げることも可能と思われます。

ソケット通信プラグインを使えば、もうちょっとスマートな方法で動的な応答が実現できるのかもしれません。

blog comments powered by Disqus