LoginSignup
2
6

More than 5 years have passed since last update.

60: Raspberry Pi 3 でデータを保存する

Last updated at Posted at 2018-06-09

はじめに

こちらは
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 してから利用する。

指定したファイル名でファイルを追記モードで開いて、データを書き込む。ここでのデータは変数ではなくて、完全に手動で作成した文字列のデータである。

070_csv.py
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()関数は、指定した区切り文字で処理すると、そのようなデータを返す。

071_csv.py
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 などで処理しやすいかもしれない。日付のフォーマットも自由に指定できるので、後々どう活用するかで決めればよいだろう。

072_csv_time.py
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生成の例
data =  v1.get() + "," + v2.get() + "," + v3.get() + "," + v4.get()

これで CSV形式で日時を付加しつつ、データを保存できるようになった。

JSON

JavaScript Object Notation

次に JSON で保存する。JSON とは RFC8259 などで規定されているデータフォーマットである。ここでは、network 経由のやりとりを想定して json を使えるようにする。JSON について詳しくは、wikipedia などを参照すればよい。

まずは、保存の前に JSONのファイルを読んで表示する処理の例である。

054-load-json.py
import json

a = open('sample.json')
b = json.load(a)

print(b)

json ファイルを開いて、loadして、printしているだけである。
しかし、これだと出力が改行されていなくて見にくい。

元の json を下記に示す。

sample.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
 }
}

こうなって一行にだーと連続表示になってしまう。

output

$ 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みたいなものである。

実行した出力はこうなる。

output
$ cat sample2.json 
{
    "profile1": {
        "coffee": 10, 
        "temp": "91"
    }, 
    "profile2": {
        "coffee": 13, 
        "temp": "93"
    }
}

きれいにindent=4で整形されている。

というわけで、同じデータを CSV と JSON形式で保存する例である。

056-dump-csv-json.py
$ 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
output
$ 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 で表示している。

056
$ 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

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6