Raspberry Piを使って室内環境をつぶやきづづける
1. 課題
- sRemo-R3で帰宅前にエアコンをONにしたつもりがついていないことがあった
- sRemoの温度センサがうまく温度を示してくれないことが多い
- 気圧の変化とかも見たい
- Twitterを県や市からのお知らせチェックくらいにしか使えていないので、なんか活用してみたかった
2. 解決策
- リビングの室温、湿度、気圧を測定する
- Raspberry Piに室温を定期的にTwitterでつぶやいてもらう
3. 手順
- Raspberry Piに温度センサを接続
- 変化をわかりやすくするためグラフを作成(温度、湿度、気圧の24時間分の変化と1週間分の変化をグラフ化して示す)
- Twythonで定期的につぶやく
- 準備したもの
- Raspberry Pi
- BME280
4. プログラム
- BME280のデータを取得
- RPiに保存してあるcsvファイルに行をずらして取得データを上書き
- グラフを描画して上書き保存
- プログラムをcronで15分おきに実行
- ①まずはBME280を使ってデータを取得するプログラム
#coding: utf-8 from smbus import SMBus import time import numpy as np bus_number = 1 i2c_address = 0x76 bus = SMBus(bus_number) digT = [] digP = [] digH = [] t_fine = 0.0 alldata = [0.0, 0.0, 0.0] def writeReg(reg_address, data): bus.write_byte_data(i2c_address,reg_address,data) def get_calib_param(): calib = [] for i in range (0x88,0x88+24): calib.append(bus.read_byte_data(i2c_address,i)) calib.append(bus.read_byte_data(i2c_address,0xA1)) for i in range (0xE1,0xE1+7): calib.append(bus.read_byte_data(i2c_address,i)) digT.append((calib[1] << 8) | calib[0]) digT.append((calib[3] << 8) | calib[2]) digT.append((calib[5] << 8) | calib[4]) digP.append((calib[7] << 8) | calib[6]) digP.append((calib[9] << 8) | calib[8]) digP.append((calib[11]<< 8) | calib[10]) digP.append((calib[13]<< 8) | calib[12]) digP.append((calib[15]<< 8) | calib[14]) digP.append((calib[17]<< 8) | calib[16]) digP.append((calib[19]<< 8) | calib[18]) digP.append((calib[21]<< 8) | calib[20]) digP.append((calib[23]<< 8) | calib[22]) digH.append( calib[24] ) digH.append((calib[26]<< 8) | calib[25]) digH.append( calib[27] ) digH.append((calib[28]<< 4) | (0x0F & calib[29])) digH.append((calib[30]<< 4) | ((calib[29] >> 4) & 0x0F)) digH.append( calib[31] ) for i in range(1,2): if digT[i] & 0x8000: digT[i] = (-digT[i] ^ 0xFFFF) + 1 for i in range(1,8): if digP[i] & 0x8000: digP[i] = (-digP[i] ^ 0xFFFF) + 1 for i in range(0,6): if digH[i] & 0x8000: digH[i] = (-digH[i] ^ 0xFFFF) + 1 def readData(): data = [] for i in range (0xF7, 0xF7+8): data.append(bus.read_byte_data(i2c_address,i)) pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4) temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4) hum_raw = (data[6] << 8) | data[7] compensate_T(temp_raw) compensate_P(pres_raw) compensate_H(hum_raw) def compensate_P(adc_P): global t_fine pressure = 0.0 v1 = (t_fine / 2.0) - 64000.0 v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5] v2 = v2 + ((v1 * digP[4]) * 2.0) v2 = (v2 / 4.0) + (digP[3] * 65536.0) v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8) + ((digP[1] * v1) / 2.0)) / 262144 v1 = ((32768 + v1) * digP[0]) / 32768 if v1 == 0: return 0 pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125 if pressure < 0x80000000: pressure = (pressure * 2.0) / v1 else: pressure = (pressure / v1) * 2 v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096 v2 = ((pressure / 4.0) * digP[7]) / 8192.0 pressure = pressure + ((v1 + v2 + digP[6]) / 16.0) # print "pressure : %7.2f hPa" % (pressure/100) pres =round((pressure/100), 2) alldata[0] = pres def compensate_T(adc_T): global t_fine v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1] v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2] t_fine = v1 + v2 temperature = t_fine / 5120.0 # print "temp : %-6.2f ℃" % (temperature) tem = round(temperature, 2) alldata[1] = tem def compensate_H(adc_H): global t_fine var_h = t_fine - 76800.0 if var_h != 0: var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) * (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h * (1.0 + digH[2] / 67108864.0 * var_h))) else: return 0 var_h = var_h * (1.0 - digH[0] * var_h / 524288.0) if var_h > 100.0: var_h = 100.0 elif var_h < 0.0: var_h = 0.0 # print "hum : %6.2f %" % (var_h) hu = round(var_h,2) alldata[2] = hu def setup(): osrs_t = 1 #Temperature oversampling x 1 osrs_p = 1 #Pressure oversampling x 1 osrs_h = 1 #Humidity oversampling x 1 mode = 3 #Normal mode t_sb = 5 #Tstandby 1000ms filter = 0 #Filter off spi3w_en = 0 #3-wire SPI Disable ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode config_reg = (t_sb << 5) | (filter << 2) | spi3w_en ctrl_hum_reg = osrs_h writeReg(0xF2,ctrl_hum_reg) writeReg(0xF4,ctrl_meas_reg) writeReg(0xF5,config_reg) setup() get_calib_param() if __name__ == '__main__': try: readData() except KeyboardInterrupt: pass np.savetxt("./alldata.csv", alldata, delimiter=",")
#-*- coding: utf-8 -*- import time import subprocess import datetime import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import time from twython import Twython APP_KEY = '取得した値' APP_SECRET = '取得した値' TOKEN_KEY = '取得した値' TOKEN_SECRET = '取得した値' twitter = Twython(APP_KEY, APP_SECRET, TOKEN_KEY, TOKEN_SECRET) #subprocessの読み込み #BME280からのデータをalldata.csvに1回分記録 subprocess.check_call(['python','./bme280_alldata.py']) #時間のデータ t = datetime.datetime.today().strftime("%H:%M") #read_csv all_data_i = np.array(np.genfromtxt("./climatedata.csv", delimiter=",")) all_data_n = all_data_i #time_input #i = 1 #all_data_n[0, 0] = -24.0 i=0 for i in range(96): #all_data_n[i,0] = -24.0 + (24*96**(-1)) * i all_data_n[i,1] = all_data_i[i+1,1] all_data_n[i,2] = all_data_i[i+1,2] all_data_n[i,3] = all_data_i[i+1,3] i = i + 1 #read_csv climate_data = np.array(np.genfromtxt("./alldata.csv", delimiter=",")) all_data_n[96,1] = climate_data[0] all_data_n[96,2] = climate_data[1] all_data_n[96,3] = climate_data[2] #csv #write np.savetxt("./climatedata.csv", all_data_n, delimiter=",") #weekly_temp tempweekly_i = np.array(np.genfromtxt("./climatedata_weekly.csv", delimiter=",")) tempweekly_n = tempweekly_i i=0 for i in range(672): tempweekly_n [i,1] = tempweekly_i[i+1,1] tempweekly_n [i,2] = tempweekly_i[i+1,2] tempweekly_n [i,3] = tempweekly_i[i+1,3] i=i+1 tempweekly_n[672,1] = climate_data[0] tempweekly_n[672,2] = climate_data[1] tempweekly_n[672,3] = climate_data[2] #write_weekly np.savetxt("./climatedata_weekly.csv", tempweekly_n, delimiter=",") ###8 week sma sma_data_i = np.array(np.genfromtxt("./simple_moving_average.csv", delimiter=",")) sma_data_n = sma_data_i i=0 for i in range(5376): sma_data_n[i,1] = sma_data_i[i+1,1] sma_data_n[i,2] = sma_data_i[i+1,2] sma_data_n[i,3] = sma_data_i[i+1,3] sma_data_n[i,4] = sma_data_i[i+1,4] sma_data_n[i,5] = sma_data_i[i+1,5] sma_data_n[i,6] = sma_data_i[i+1,6] i=i+1 sma_data_n[5376,1] = climate_data[0] sma_data_n[5376,2] = climate_data[1] sma_data_n[5376,3] = climate_data[2] #cal average sma_data_n[5376,4] = np.average(sma_data_n[4704:5376,1]) sma_data_n[5376,5] = np.average(sma_data_n[4704:5376,2]) sma_data_n[5376,6] = np.average(sma_data_n[4704:5376,3]) #saving np.savetxt("/home/pi/Documents/python/simple_moving_average.csv", sma_data_n, delimiter=",") #print tempweekly_n[:,0] #data save gs = gridspec.GridSpec(3,2) ax1 = plt.subplot(gs[0,0]) ax2 = plt.subplot(gs[0,1]) ax3 = plt.subplot(gs[1,0]) ax4 = plt.subplot(gs[1,1]) ax5 = plt.subplot(gs[2,0]) ax6 = plt.subplot(gs[2,1]) #Pressure ax1.plot(all_data_n[:,0], all_data_n[:,1], color='blue') ax1.set_title('Last 24 hours', fontsize=8) ax1.set_xlim([-24,0]) ax1.set_xticks([-24, -18, -12, -6, 0]) ax1.set_xticklabels([]) ax1.set_ylabel("P [hPa]", fontsize=10) ax1.tick_params(labelsize=8) ax1.grid(True, color='gray') ax2.plot(tempweekly_n[:,0], tempweekly_n[:,1], color='violet') ax2.set_title('Last 1 week', fontsize=8) ax2.set_xlim([-7,0]) ax2.set_xticks([-7, -6, -5, -4, -3, -2, -1, 0]) ax2.set_xticklabels([]) ax2.tick_params(labelsize=8) ax2.grid(True, color='gray') #Temperature ax3.plot(all_data_n[:,0], all_data_n[:,2], color='blue') ax3.set_xlim([-24,0]) ax3.set_xticks([-24, -18, -12, -6, 0]) ax3.set_xticklabels([]) ax3.set_ylabel("T [C]", fontsize=10) ax3.tick_params(labelsize=10) ax3.grid(True, color='gray') ax4.plot(tempweekly_n[:,0], tempweekly_n[:,2], color='violet') ax4.set_xlim([-7,0]) ax4.set_xticks([-7, -6, -5, -4, -3, -2, -1, 0]) ax4.set_xticklabels([]) ax4.tick_params(labelsize=10) ax4.grid(True, color='gray') #Humidity ax5.plot(all_data_n[:,0], all_data_n[:,3], color='blue') ax5.set_xlim([-24,0]) ax5.set_xticks([-24, -18, -12, -6, 0]) ax5.set_xticklabels(["-24", "-18", "-12", "-6", "0"]) ax5.set_ylabel("H [%]", fontsize=10) ax5.tick_params(labelsize=10) ax5.grid(True, color='gray') ax6.plot(tempweekly_n[:,0], tempweekly_n[:,3], color='violet') ax6.set_xlim([-7,0]) ax6.set_xticks([-7, -6, -5, -4, -3, -2, -1, 0]) ax6.set_xticklabels(["-7", "-6", "-5", "-4", "-3", "-2", "-1", "0"]) ax6.tick_params(labelsize=10) ax6.grid(True, color='gray') #plt.figure(figsize=(5,10), dpi=75) plt.savefig("./climate.jpg", figsize=(4,10), dpi=75, bbox_inches="tight") photo = open("./climate.jpg", 'rb') response = twitter.upload_media(media=photo) twitter.update_status(status=str(t) +'における室温は ' + str(climate_data[1]) + '℃, 湿度は ' \ + str(climate_data[2])+ '%, 気圧は ' + str(climate_data[0]) +'hPa 🌏 ', media_ids=[response['media_id']])
5. 運用した感想
- 室温がわかるのでエアコンがちゃんと付いたかどうか分かる
- 温度、湿度、気圧をグラフ化したので暖かくなってきたのか、寒くなってきたのかがわかってよい
- 古いデータも過去のツイートで辿れる(どこかでまとめておいたほうがそのうち分析とかで遊べそうですが・・・)
■参考にしたページ
- BME280について
ラズベリーパイで温度・湿度・気圧をまとめて取得!AE-BME280でIC2通信 | Device Plus - デバプラ
- Twythonについて