Raspberry Piで記録する温度、湿度などのログをローテーションする
これは何
Raspberry Pi 4にて記録中の室温などの環境データのファイルがなかなかのサイズになってきたので
- logging機能を使って、データファイルをローテーション
- データを収集する機会が増えることが予想されるためデータファイルをcsvからjsonに移行
を行うこととしました。
環境
- Raspberry Pi 4
- Linux raspi4 5.4.42-v8+ #1319 SMP PREEMPT Wed May 20 14:18:56 BST 2020 aarch64 GNU/Linux
- 気圧・気温・湿度センサー(BME280)
- Python 3.8.7 (default, Jan 27 2021, 11:28:25)
作業方針
BME280の設定
Switch Scienceのgithubから入手したbme280_sample.pyを2to3を使用して変換して
% 2to3-2.7 -w bme280_sample.py
bme280.pyにコピーして、以下を修正
$ diff bme280_sample.py bme280.py
69,71c69
< compensate_T(temp_raw)
< compensate_P(pres_raw)
< compensate_H(hum_raw)
---
> return compensate_T(temp_raw), compensate_P(pres_raw), compensate_H(hum_raw)
95c93
< print("pressure : %7.2f hPa" % (pressure/100))
---
> return pressure/100
103c101
< print("temp : %-6.2f ℃" % (temperature))
---
> return temperature
117c115
< print("hum : %6.2f %" % (var_h))
---
> return var_h
loggingの設定から温度などの読み出しまで
ちゃちゃっと行きます。
まずは、thp_logger.pyとproject_logging.pyを作成します。
- bme280.py
- project_logging.py
をthp_logger.pyでインポートし、thp_logger.pyを実行します。
thp_logger.pyは、こんな感じにしました。
#coding: utf-8
import time
import datetime
import os
import bme280
import logging
from project_logging import getLogger
logger = getLogger(__name__)
def main():
mesuredData = []
mesuredData = bme280.readData()
logger.info({'timestamp':time.time(),'temp(deg.)': mesuredData[0],'pressure(hPa)':mesuredData[1],'humid.(%)':mesuredData[2]})
if __name__ == '__main__':
while True:
main()
time.sleep(1)
time.sleep()は、お好みでどうぞ。
おつぎは、project_logging.pyです。
import logging
import datetime
from pytz import timezone
from pythonjsonlogger import jsonlogger
import logging.handlers
now = datetime.datetime.now()
filename = now.strftime("%Y%m%d") +'_thpLog.json'
# https://github.com/madzak/python-json-logger#customizing-fields
class JsonFormatter(jsonlogger.JsonFormatter):
def parse(self):
"""
他に出したいフィールドがあったらこのリストに足す
https://docs.python.jp/3/library/logging.html
"""
return [
'process',
'timestamp',
'level',
'temp(deg.)',
'pressure(hPa)',
'humid.(%)',
]
def add_fields(self, log_record, record, message_dict):
super().add_fields(log_record, record, message_dict)
if not log_record.get('timestamp'):
# https://qiita.com/yoppe/items/4260cf4ddde69287a632
now = datetime.datetime.now(timezone('Asia/Tokyo')).strftime('%Y-%m-%dT%H:%M:%S%z')
log_record['timestamp'] = now
if log_record.get('level'):
log_record['level'] = log_record['level'].upper()
else:
log_record['level'] = record.levelname
def getLogger(module_name):
"""プロジェクトごとにハンドラの設定などをしたい場合はここでやる"""
logger = logging.getLogger(module_name)
#handler = logging.FileHandler(filename, mode="w")
handler = logging.handlers.TimedRotatingFileHandler(filename, encoding='utf-8',
when='S',
interval=10,
backupCount=5,)
handler.suffix = "%Y-%m-%d_%H%M%S.json"
formatter = JsonFormatter()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
return logger
テスト用に10秒ごとでローテーションするようにしていますが、実際の運用時にはwhenに月曜日始まりのW0を設定するつもりです。
詳細は、公式ドキュメントで確認ください。
稼働風景
1秒ごとセンサーデータを取得して、10秒ごとにログローテーションする設定での動作です。
jsonファイルのpandasからの読み出し
import json
import pandas as pd
filename = '20210202_thpLog.json'
df = pd.read_json(filename, lines=True)
print(df)
で読み出すことができます。あとは、ご自由に。
PS E:\Dropbox\00_works\Python\20210202_\json> python .\readJson.py
process timestamp level temp(deg.) pressure(hPa) humid.(%)
0 19035 2021-02-02 10:40:22.837137920 INFO 23.369868 1000.237530 33.152283
1 19035 2021-02-02 10:40:23.839900416 INFO 23.364816 1000.228997 33.072454
2 19035 2021-02-02 10:40:24.842537984 INFO 23.364816 1000.282805 32.972641
3 19035 2021-02-02 10:40:25.845187328 INFO 23.369868 1000.237530 32.912729
4 19035 2021-02-02 10:40:26.847422208 INFO 23.369868 1000.237530 32.822892
... ... ... ... ... ... ...
2653 19035 2021-02-02 11:24:43.185660416 INFO 23.051628 1000.587428 29.506088
2654 19035 2021-02-02 11:24:44.188551680 INFO 23.051628 1000.533646 29.531049
2655 19035 2021-02-02 11:24:45.191405824 INFO 23.051628 1000.479865 29.645868
2656 19035 2021-02-02 11:24:46.194267136 INFO 23.056680 1000.542184 29.950316
2657 19035 2021-02-02 11:24:47.197230080 INFO 23.056680 1000.569075 29.815537
[2658 rows x 6 columns]
補足(タイムゾーンの変換)
上記のスクリプトだと、デフォルトでtimestampの値が日付に変換されてしまいます。
(詳しくはこちらを確認してください。)
これはよろしくないので、タイムゾーンを変換します。
私の場合はpyqtgraphを使うのでunixtimeでOKですが、JSTに変換する場合も記載します。
import pandas as pd
filename = '20210202_thpLog.json'
# timezoneをJSTに変換する場合
df_jst = pd.read_json(filename, lines=True).set_index('timestamp').tz_localize('UTC').tz_convert('Asia/Tokyo')
print(df_jst)
# unixtimeのまま使用する場合
df_unixtime = pd.read_json(filename, lines=True, convert_dates=False)
print(df_unixtime)
上記を実行すると以下のようになります。
タイムゾーンの変換は、indexのみが対象となるようでして。。。
timestampをindex列にしてから、タイムゾーンの変換を行っています。
PS E:\Dropbox\00_works\Python\20210202_\json> python .\readJson.py
process level temp(deg.) pressure(hPa) humid.(%)
timestamp
2021-02-02 19:40:22.837137920+09:00 19035 INFO 23.369868 1000.237530 33.152283
2021-02-02 19:40:23.839900416+09:00 19035 INFO 23.364816 1000.228997 33.072454
2021-02-02 19:40:24.842537984+09:00 19035 INFO 23.364816 1000.282805 32.972641
2021-02-02 19:40:25.845187328+09:00 19035 INFO 23.369868 1000.237530 32.912729
2021-02-02 19:40:26.847422208+09:00 19035 INFO 23.369868 1000.237530 32.822892
... ... ... ... ... ...
2021-02-02 20:24:43.185660416+09:00 19035 INFO 23.051628 1000.587428 29.506088
2021-02-02 20:24:44.188551680+09:00 19035 INFO 23.051628 1000.533646 29.531049
2021-02-02 20:24:45.191405824+09:00 19035 INFO 23.051628 1000.479865 29.645868
2021-02-02 20:24:46.194267136+09:00 19035 INFO 23.056680 1000.542184 29.950316
2021-02-02 20:24:47.197230080+09:00 19035 INFO 23.056680 1000.569075 29.815537
[2658 rows x 5 columns]
process timestamp level temp(deg.) pressure(hPa) humid.(%)
0 19035 1.612262e+09 INFO 23.369868 1000.237530 33.152283
1 19035 1.612262e+09 INFO 23.364816 1000.228997 33.072454
2 19035 1.612262e+09 INFO 23.364816 1000.282805 32.972641
3 19035 1.612262e+09 INFO 23.369868 1000.237530 32.912729
4 19035 1.612262e+09 INFO 23.369868 1000.237530 32.822892
... ... ... ... ... ... ...
2653 19035 1.612265e+09 INFO 23.051628 1000.587428 29.506088
2654 19035 1.612265e+09 INFO 23.051628 1000.533646 29.531049
2655 19035 1.612265e+09 INFO 23.051628 1000.479865 29.645868
2656 19035 1.612265e+09 INFO 23.056680 1000.542184 29.950316
2657 19035 1.612265e+09 INFO 23.056680 1000.569075 29.815537
[2658 rows x 6 columns]
参考にさせて頂いたサイト
ログ出力のための print と import logging はやめてほしい - Qiita
pythonでjson形式でログを出す - Qiita
Author And Source
この問題について(Raspberry Piで記録する温度、湿度などのログをローテーションする), 我々は、より多くの情報をここで見つけました https://qiita.com/mashi0727/items/d19186759c52cbba60e9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .