土曜日は近めの場所で朝ライド。
渡月橋を渡る時、ちょうど山に満月がかかっていました。
昼からはお仕事。報告書がなかなか仕上がらず、指も腱鞘炎気味になってきて苦労しました。
日曜日はそれで遅寝。長野からきた人たちとの交流ライドがあったのですが、参加できず。
10時ごろ起きた後、ぼちぼち自作AI?スピーカーのぶんちゃんの改良に取り組みました。まずはミキサーの正常動作確立。これまで音出力のミキサー機能がうまく働かず、さらにはpodcastを流すソフトを動かしていると、それを一時停止して音が出ない状態になっていても、出力が占有されて何も喋れないとか、結構困っていました。
一応linuxの音関係を司るalsaシステムにはソフトウェアミキサー のdmixがついているのですが、私がmp3ファイルを流すのに使っているmplayerというソフトがうまく対応できません。サンプリングレートの違いを補完できないようです。色々調べていてalsaplayerというソフトはうまくいくことがわかったのですが、こいつにはバグがあり、一時停止してからそれを解除すると再生速度が増加してしまいます。ソースコードを解析して、おかしいところを見つけている人がいて、最新版をコンパイルして入れ直したのですが、今度は全く再生できず。困り果てた挙句、一時停止解除後にスピードを読み取って100%でなければ100%に戻すというプログラムをAIスピーカー側にいれました。
それと、スイッチを押すとニュースが流れるプログラムはAIスピーカー側に統合。起動は声で行い、一時停止のみスイッチが効くようにしました。あとはxml取得解析機能を拡張して、今日の天気だけでなく、明日の天気、および花粉情報を教えてくれる機能もつけました。花粉情報は環境省のはなこさんの1時間ごと実測値。でも細かすぎるので6時間ごとの平均値を喋るようにしました。
今後は近くの駅の直近の電車の時間なども教えてくれるようにしたいですね。
そうしているうちに夕方の5時。「汽船でおでん」というイベントに出かける時間です。以前に参加した「おでんしゃ」というイベントの姉妹編です。ちょっとぎりぎりになったのでJRで大津まで行って、そこから大津港まで歩きました。
船の中でおでんというわけではなく、船で会場まで移動して創作おでんというものでした。会場はちょっとレトロな建物。ワインも3杯でて満足でした。
今日は東京出張。朝から大雨で駅まで移動するのが大変でした。タクシーが全然来ないので、結局レインコートを着て、自転車で移動。東京に着くと今度はひどい風。
まあ仕事は無事済んで、新幹線の中でハンバーグと焼売を食べて京都駅へ。湖西線が風で止まっていた影響か、西行きも結構遅れていました。
雨は止んでいてやれやれでした。
# -*- coding: utf-8 -*- import subprocess import socket from time import sleep import time import xml.etree.ElementTree as ET import pigpio import subprocess from datetime import datetime parser=ET.XMLParser(encoding='utf-8') #sleep(10) host = "localhost" port = 10500 sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((host, port)) except socket.error: subprocess.Popen(['bash','/home/pi/julius/Julius.sh']) sleep(5) sock.connect((host, port)) data ="" timer_pid=None start_time=time.time() check_time=time.time()-10 subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) subprocess.Popen(['alsaplayer','-i','daemon','-q']) pi=pigpio.pi() pi.set_mode(4,pigpio.INPUT) pi.set_pull_up_down(4,pigpio.PUD_UP) pi.set_glitch_filter(4,50000) def cb_interrupt(gpio,level,tick): print('edge detect') subprocess.Popen(['alsaplayer','--pause']) ret=subprocess.Popen(['alsaplayer','--status'],stdout=subprocess.PIPE).stdout.readlines() if ': 0%' in ret[4]: subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) else: subprocess.Popen(['alsaplayer','--speed','1']) subprocess.Popen(['amixer','-c','1','sset','Mic',str(15)]) cp=pi.callback(4,pigpio.FALLING_EDGE, cb_interrupt) def say_sentence(sentence): subprocess.Popen(['amixer','-c','1','sset','Speaker',str(30)]) subprocess.Popen(['amixer','-c','1','sset','Mic',str(0)]) subprocess.call(['bash','/home/pi/scripts/jsay.sh',sentence]) subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) def say_sentence_low(sentence): subprocess.Popen(['amixer','-c','1','sset','Mic',str(0)]) subprocess.Popen(['amixer','-c','1','sset','Speaker',str(20)]) subprocess.call(['bash','/home/pi/scripts/jsay.sh',sentence]) subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) def say_timer_count(start_time): elapse=time.time()-start_time minutes=int(elapse/60) seconds=int(elapse-60*minutes) if minutes==0: say_sentence('タイマーは今'+str(seconds)+'秒です') else: say_sentence('タイマーは今'+str(minutes)+'分'+str(seconds)+'秒です') def start_news(): say_sentence_low('NHKニュースを流します') subprocess.Popen(['amixer','-c','1','sset','Speaker',str(25)]) subprocess.Popen(['amixer','-c','1','sset','Mic',str(15)]) subprocess.Popen(['sh','/home/pi/.podracer/pod.sh']) def start_trendy(): say_sentence_low('日経トレンディを流します') subprocess.Popen(['amixer','-c','1','sset','Speaker',str(18)]) subprocess.Popen(['amixer','-c','1','sset','Mic',str(15)]) subprocess.Popen(['sh','/home/pi/.podracer/pod_trendy.sh']) def start_music(): say_sentence_low('クラッシックを流します') subprocess.Popen(['amixer','-c','1','sset','Mic',str(15)]) subprocess.Popen(['amixer','-c','1','sset','Speaker',str(20)]) subprocess.Popen(['sh','/home/pi/.podracer/pod_classic.sh']) def stop_podcast(): subprocess.Popen(['alsaplayer','--stop']) subprocess.Popen(['alsaplayer','--clear']) say_sentence_low('ポッドキャストを止めました') subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) def tenki(day): subprocess.Popen(['amixer','-c','1','sset','Mic',str(0)]) subprocess.Popen(['amixer','-c','1','sset','Speaker',str(30)]) if day=='today': subprocess.call(['python','/home/pi/julius/tenki.py']) elif day=='tomorrow': subprocess.call(['python','/home/pi/julius/tenki_tomorrow.py']) subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) def pollen(): subprocess.Popen(['amixer','-c','1','sset','Mic',str(0)]) subprocess.Popen(['amixer','-c','1','sset','Speaker',str(30)]) subprocess.call(['python','/home/pi/julius/pollen.py']) subprocess.Popen(['amixer','-c','1','sset','Mic',str(35)]) def start_timer(): if check_mplayer() != None: stop_podcast() timer_pid=subprocess.Popen(['sh','/home/pi/scripts/timer.sh']).pid start_time=time.time() return(timer_pid,start_time) def stop_timer(): say_sentence_low('タイマーを停止します') subprocess.Popen(['kill',str(timer_pid)]) return(None) def IsStop(strTemp): return( ('ストップ' in strTemp) or ('止めて' in strTemp) or ('停止' in strTemp)) def IsStart(strTemp): return( ('スタート' in strTemp) or ('開始' in strTemp)) def IsTime(strTemp): return(('何分' in strTemp) or ('今' in strTemp) or ('何秒' in strTemp)) while True: if '</RECOGOUT>\n.' in data: root=('<?xml version="1.0"?>\n'+data[data.find('<RECOGOUT>'):(data.find('/RECOGOUT>')+10)].replace('\n.','').replace('<s>','s').replace('</s>','s')) print(root) root=ET.fromstring('<?xml version="1.0" encoding="utf-8"?>\n'+data[data.find('<RECOGOUT>'):(data.find('/RECOGOUT>')+10)].replace('\n.','').replace('<s>','s').replace('</s>','s')) word=[] cm=[] for whypo in root.findall('./SHYPO/WHYPO'): word.append((whypo.get('WORD')).encode('utf_8')) cm.append(float(whypo.get('CM'))) strTemp="" for i in range(len(word)): if '文ちゃん' in word[i] and cm[i] >0.95: strTemp='文ちゃん' for j in range (i+1,len(word)): if cm[j] >0.60: strTemp=strTemp+' '+word[j] break print(strTemp) if '文ちゃん' in strTemp: if '天気' in strTemp: if '明日' in strTemp: tenki('tomorrow') elif '今日' in strTemp: tenki('today') elif datetime.now().hour >18: tenki('tomorrow') else: tenki('today') elif '日経トレンディ' in strTemp: if check_mplayer() == None: start_trendy() elif IsStop(strTemp): stop_podcast() elif 'NHKニュース' in strTemp: if check_mplayer()==None: start_news() elif IsStop(strTemp): stop_podcast() elif '音楽' in strTemp : if check_mplayer()==None: start_music() elif IsStop(strTemp): stop_podcast() elif 'タイマー' in strTemp: if time.time()-start_time >3600: timer_pid=None#起動後60分以上経つとタイマーは消す if timer_pid==None: if IsStart(strTemp): timer_pid,start_time=start_timer() elif IsStop(strTemp) or IsTime(strTemp): say_sentence_low('タイマーは動かしてません') else: timer_pid,start_time=start_timer() elif IsStop(strTemp): timer_pid=stop_timer() elif IsStart(strTemp) or IsTime(strTemp): say_timer_count(start_time) else: say_timer_count(start_time) elif '花粉' in strTemp: pollen() elif IsTime(strTemp): if time.time()-start_time >3600: timer_pid=None#起動後60分以上経つとタイマーは消す if timer_pid==None: say_sentence_low('タイマーは動かしてません') else: say_timer_count(start_time) elif IsStop(strTemp): if timer_pid!=None: timer_pid=stop_timer() elif check_mplayer() != None: stop_podcast() else: say_sentence_low(' はーい!、なんでしょうか?') data="" else: try: data+=str(sock.recv(1024)) except socket.error: subprocess.Popen(['bash','/home/pi/julius/Julius.sh']) sleep(5) sock.connect((host, port)) data+=str(sock.recv(1024))