はじめに
こちらは
Arduino と Raspberry Pi の違いのまとめ
の個別記事で、Raspberry Pi 3 でデータを保存する。
目的
Raspberry Pi3 で動作する python の GUI アプリケーションの動作ログを残したい。設定したパラメータを記録して、それが実際にどうだったか振り返り、次の動作に反映させるためである。
microSD カードから起動する Raspberry Pi3 は、同時にファイルを保存することもできる。Arduino でもできることではあるが、今後、network 経由の保存となると、Ethernet Shield を使うとか、無線対応の Arduino 使うとかになって、価格も高くなってくるので Eternet および Wi-Fi が標準でついている Raspberry Pi3 を使うことにする。
ここでは、CSV と、JSON の二つを読み書きする。
CSV
まずは、カンマで区切ったデータ、いわゆる CSV を作る。CSV なら Excel などで読み込んで処理しやすいからである。library は import csv してから利用する。
指定したファイル名でファイルを追記モード
で開いて、データを書き込む。ここでのデータは変数ではなくて、完全に手動で作成した文字列のデータである。
import csv
with open('a1-log.csv','a') as f:
writer = csv.writer(f)
writer.writerow([1,'audio','100'])
writer.writerow([2,'video','568'])
writer.writerow([3,'movie','1250'])
f.close()
print('done. see a1-log.csv')
1,audio,100
2,video,568
3,movie,1250
次。元のデータをsplit()で分割する場合。split()関数は、指定した区切り文字で処理すると、そのようなデータを返す。
import csv
word = "Good morning, Hello, Good night, bye, bye-bye"
words = word.split(',')
with open('start.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(words)
f.close()
print("done. see start.csv.")
Good morning, Hello, Good night, bye, bye-bye
さて、ここまでで複数の変数のデータを CSV で保存することができるようになった。次に、CSV の生成時にその日時をつけて、データをはき出す処理を付加する。日時がないと、いつの動作logか分からなくなるためである。先頭の rec_ とかないほうが後で Excel などで処理しやすいかもしれない。日付のフォーマットも自由に指定できるので、後々どう活用するかで決めればよいだろう。
import csv
import datetime
now = datetime.datetime.now()
recordtime = 'rec_{0:%Y%m%d}'.format(now)
print("recordtime = %s" % recordtime)
data = "foo,bar,baz"
data = recordtime + "," + data
data = data.split(',')
print("data= %s" % data)
with open('log.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(data)
f.close()
print("loggging done. see log.csv")
rec_20180606,foo,bar,baz
実際のアプリケーションでは、data のところを 変数名.get() などで取得してきて、自分で CSV 形式を作って保存すればよい。例はこちら。
data = v1.get() + "," + v2.get() + "," + v3.get() + "," + v4.get()
これで CSV形式で日時を付加しつつ、データを保存できるようになった。
JSON
JavaScript Object Notation
次に JSON で保存する。JSON とは RFC8259 などで規定されているデータフォーマットである。ここでは、network 経由のやりとりを想定して json を使えるようにする。JSON について詳しくは、wikipedia などを参照すればよい。
まずは、保存の前に JSONのファイルを読んで表示する処理の例である。
import json
a = open('sample.json')
b = json.load(a)
print(b)
json ファイルを開いて、loadして、printしているだけである。
しかし、これだと出力が改行されていなくて見にくい。
元の json を下記に示す。
{
"coffee":{
"vendor": "Morihico",
"roast_type": "French",
"roast_date": "2018-06-09"
},
"configuration":{
"temp": 93,
"profile": 1,
"first_pour": 2.3,
"steam": 30,
"pour": 2.4,
"wait": 8.0,
"repeat": 5
}
}
こうなって一行にだーと連続表示になってしまう。
$ python 054-load-json.py
{u'coffee': {u'roast_date': u'2018-06-09', u'roast_type': u'French', u'vendor': u'Morihico'}, u'configuration': {u'profile': 1, u'repeat': 5, u'temp': 93, u'first_pour': 2.3, u'pour': 2.4, u'steam': 30, u'wait': 8.0}}
次にファイルからではなくて、プログラム内でJSONのフォーマットを作って出力する例である。
py:055-dump-json.py
import json
v1 = 10
v2 = 13
dic = {
"profile1": {
"coffee" : v1,
"temp" : "91"
} ,
"profile2" : {
"coffee" : v2,
"temp" : "93"
}
}
a = open('sample2.json', 'w')
json.dump(dic, a , indent=4)
print("done. check sample2.json")
dic でデータを作り、openでファイルを新規に開き、dumpしている。出力のindent数を決めることができる。ここでは4である。
最後のprintは単にどのファイルを見たらよいかの自分用のhelpみたいなものである。
実行した出力はこうなる。
$ cat sample2.json
{
"profile1": {
"coffee": 10,
"temp": "91"
},
"profile2": {
"coffee": 13,
"temp": "93"
}
}
きれいにindent=4で整形されている。
というわけで、同じデータを CSV と JSON形式で保存する例である。
$ python 056-dump-csv-json.py
recordtime = 2018-06-16-0842
data= ['2018-06-16-0842', 'foo', 'bar', 'baz']
loggging done. see log.csv
loggging done. see log.json
$ cat log.csv
2018-06-16-0842,foo,bar,baz
$ cat log.json
{
"log1": {
"date": "2018-06-16-0842",
"name2": "bar",
"name3": "baz",
"name1": "foo"
}
}
これを実現するためのsampleはこちら。 共通部分は、日付を出すところで、その後、CSV と JSON で表示している。
$ cat 056-dump-csv-json.py
# modules
import csv
import json
import datetime
# date
now = datetime.datetime.now()
recordtime = '{0:%Y-%m-%d-%H%M}'.format(now)
print("recordtime = %s" % recordtime)
# CSV
data = "foo,bar,baz"
data = recordtime + "," + data
data = data.split(',')
print("data= %s" % data)
with open('log.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(data)
f.close()
print("loggging done. see log.csv")
# JSON
v1 = "foo"
v2 = "bar"
v3 = "baz"
dic = {
"log1": {
"date": recordtime,
"name1" : v1,
"name2" : v2,
"name3" : v3
}
}
f_json = open('log.json', 'w')
json.dump(dic, f_json, indent=4)
print("loggging done. see log.json")
まとめ
これで自分の好きな形式に CSV と JSON で保存できるようになった。
次はこれらの保存データを使ってグラフ描画を行う。
参考web site
[1] python documentation - 13.1. csv — CSV File Reading and Writing, https://docs.python.org/2.7/library/csv.html#module-csv
[2] python documentation - 18.2. json — JSON encoder and decoder, https://docs.python.org/2.7/library/json.html?highlight=json
[3] RFC8259, https://tools.ietf.org/html/rfc8259