#Raspberry Piの共有フォルダにファイルが置かれると処理を実行する
1.ラズパイに共有フォルダをつくる
2.共有フォルダの状態を監視
3.フォルダに更新があったら、処理を実行
この例では、
・ラズパイの共有フォルダにExcelファイル(xls,xlsx)が置かれると
matplotlibでグラフを描いてEPS出力
・さらにeps→emf形式に変換したファイルを出力する
実行する処理のサンプルはここまでメモってきたプログラムです。
(1)Excelデータをmatplotlibでグラフ化する(1)
(2)[matplotlibのグラフをemfファイル形式に変換]
(http://qiita.com/gitytm15/items/418ddcd8f58555d7433b)
(3)ラズパイのInkscapeを0.48から0.92にしてみた
ラズパイなのでずっと起動してても、それほど気にすることはないというのが気に入っています。
#1.ラズパイに共有フォルダをつくる
共有の[DATA]フォルダ内にxlsx,xlsファイルをいれるとプログラムが実行されるようにするために、まずはどこからでもアクセスできる共有フォルダを作成します。
[share] ←共有フォルダ
│
└[DATA] ここにxlsx,xlsをおくと変換プログラムが実行されるようにする
│
├[eps] epsファイル保存
└[emf] emfファイル保存
参考にするところは検索でもたくさんでてきますがラズパイのsambaによる共有方法は、ここを参考にしました。
[hiramine.com]
(http://www.hiramine.com/physicalcomputing/raspberrypi3/samba_installconfigconnect.html)
ここでは/home/pi
を共有化されていますが、pi以下が丸見えだと困るので、さらにその下に[share]
フォルダを作ることにしました。
はじめは、この[share]
とpath=/home/share
のフォルダ名を合わせていなくて、共有がうまくいかず、しばらく悩んでいました。おおざっぱな流れはつぎのようになります。
インストール
sudo apt-get update
sudo apt-get install samba
設定ファイルの書き換え(最後の行に追記)
sudo nano /etc/samba/smb.conf
#最後に追加
[share]
path = /home/pi/share
read only = No
guest ok = Yes
force user = pi
sudo service smbd restart
これでWindows,Mac,Ubuntuからアクセスできるようになりました。
#2.共有フォルダの状態を監視
監視する方法と実際の処理について具体的なコードですが、すでにわかりやすい記事があります。しっかり参考にさせていただきました。つかったものはwatchdog
です
・[ファイル監視にwatchdogがかなり便利な件]
(http://qiita.com/PyYoshi@github/items/9744a138c018734c69db)
・[Pythonで作るLaTex自動コンパイル環境]
(http://qiita.com/syutaro/items/414fc12eeb8960b3c29b)
・[watchdog 0.8.3 Example API Usage]
(https://pypi.python.org/pypi/watchdog)
watchdogはpip install watchdog
でインストールできます。念の為。
#3.更新があったら実行
コードは下のsample1.pyを参照してください。これが監視して実行するメインの部分となります。
簡単な説明
watchdogまわりのimportに加えて実行用のモジュールをimportします。
import sample2
ここではsample2.pyのなかのコードを実行するためにこうしています。
(この部分を任意の実行ファイルに置き換える)
sample2.pyは、下の2つのコードをまとめています。
Excelデータをmatplotlibでグラフ化する(1)
[matplotlibのグラフをemfファイル形式に変換]
(http://qiita.com/gitytm15/items/418ddcd8f58555d7433b)
ファイル更新の監視対象は、ここではExcelファイルなので、拡張子をこのように設定します。
# 監視対象のファイル
observed_file_type = ('.xls','.xlsx')
さきほど作成したラズパイの共有フォルダをBASEDIRに設定します。
元々は、BASEDIRは、ファイル本体の場所を示す
#BASEDIR = os.path.abspath(os.path.dirname(__file__))
になっていますが、ここではコメントアウトしています。今回はラズパイの共有フォルダのアドレスを次のように指定しています。
BASEDIR ='/home/pi/share/DATA'
つぎにイベント発生時の実行部分です。このコードがイベント毎に入ります。更新のあったExcelファイルのパスを投げています。
sample2.plot(event.src_path) #ファイル作成時に実行
sample1.pyを実行するとラズパイ君が指定フォルダの監視モードに入ります。
指定のフォルダにExcelファイルを移動したり、編集して保存するとその都度実行されます。
このExcelファイルはXY軸プロットでA1にX、B1にYをいれる構造に対応しています。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import os
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
import sample2 #←更新にあわせて実行するモジュール(ここでは仮にsample2)
# 監視対象のファイル
observed_file_type = ('.xls','.xlsx')
# 設定
#BASEDIR = os.path.abspath(os.path.dirname(__file__))
#→このプログラムファイルが置かれている場所を監視する場合はこれ
#ラズパイの共有フォルダを指定
#共有フォルダ[share]内に、[DATA]フォルダを配置した
BASEDIR ='/home/pi/share/DATA'
# 変更したファイルが監視対象であるかを調べる
def match(path):
return any([path.endswith(ft) for ft in observed_file_type])
# 変更時のイベントハンドラ
class ChangeHandler(FileSystemEventHandler):
def on_create(self, event):
if event.is_directory:
return
if match(event.src_path):
print('Create',event.src_path)
sample2.plot(event.src_path) #ファイル作成時に実行
def on_modified(self, event):
if event.is_directory:
return
if match(event.src_path):
print('Modified',event.src_path)
sample2.plot(event.src_path) #ファイル変更時に実行
def on_deleted(self, event):
if event.is_directory:
return
if match(event.src_path):
print('delete',event.src_path)
#ファイルが消された時はなにもしない
if __name__ in '__main__':
event_handler = ChangeHandler()
observer = Observer()
observer.schedule(event_handler, BASEDIR, recursive=True)
print('start dir=',BASEDIR)
observer.start()
try:
while True:
time.sleep(0.1)
except KeyboardInterrupt:
observer.stop()
observer.join()
#4.プロットとファイル変換用のモジュール
Excelファイルの更新や新規にファイルが作成されたタイミングで呼びだされます。
Excelのパスが投げられてきますので、このExcelファイルを読み込みグラフ化します。
そのあと、グラフ描画を行い、eps形式で保存すると同時にsvgからemfファイルへ変換を行い保存します。元のsvgファイルは削除します。
必要なモジュールは以下のとおりです。
・pandas
・matplotlib
・subprocess
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import subprocess
import os
# フォントファイルの場所を指定 ubuntu (C:\Windows\Fonts\任意のFont)
fp = FontProperties(fname="/usr/share/fonts/truetype/fonts-japanese-gothic.ttf")
def dataload(path): #Pandas DataFrameに読込み
df=pd.read_excel(path)
return df
def graph(df):
#データフレームからx軸とY軸データを読み込む
#列で指定
x=df[[0]]
y=df[[1]]
#Graph
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_yscale('linear')
#ax1.set_yscale('log')
#ax1.set_ylim(-1.1, 1.1)
#ax1.set_xlim(0,360)
ax1.set_title("グラフ sample",fontdict = {"fontproperties": fp},fontsize=12)
ax1.set_xlabel("x軸",fontdict = {"fontproperties": fp},fontsize=12)
ax1.set_ylabel("y軸",fontdict = {"fontproperties": fp},fontsize=12)
ax1.scatter(x, y,s=1,c='r',label='sin')
ax1.legend(loc="upper right")
def graph_save(path):
SAVEDIR=os.path.dirname(path) #ファイルパス
fname, ext = os.path.splitext( os.path.basename(path) ) #ファイル名のみ
plt.savefig(SAVEDIR+'/eps/'+fname+".eps") #eps保存
plt.savefig(SAVEDIR+fname+".svg") #emf変換のためにsvgで保存
call_cmd='inkscape ' + SAVEDIR+fname + '.svg -M ' + SAVEDIR+'/emf/'+fname +'.emf'
subprocess.call(call_cmd,shell=True)
os.remove(SAVEDIR+fname+".svg") #svgはいらないので削除する
def plot(path):
#監視用プログラムから呼び出される
df=dataload(path) #Excelをpandasデータフレームとして読み込む
graph(df) #matplotでグラフ描画
graph_save(path) #グラフを保存・変換する
if __name__ == '__main__':
SAVEDIR='/home/pi/share/DATA/'
path='/home/pi/Desktop/sample.xlsx'
plot(path)
以上