Ceci est le 4e message de Qiita. Inexpérimenté dans l'industrie informatique et la définition des mots peut être erronée. Si vous avez un avis, j'apprécierais que vous me donniez quelques conseils.
Ma maison est une maison en bois de 25 ans, et le premier étage est très froid en hiver et le deuxième étage est modérément chaud en été. Aussi, probablement parce que c'est un bâtiment en bois, je sens que la température à l'intérieur de la maison change lentement. Par exemple, il fait frais de 9 h à 11 h en juin, mais l'intérieur de la maison devient humide vers 19 h le soir.
Par conséquent, je voulais mesurer les données de température à différentes saisons et lieux, j'ai donc essayé d'acquérir des données de température et de traiter les données avec Rasberry Pi.
Je voulais vraiment mesurer et comparer les températures à plusieurs endroits en même temps, mais en raison de contraintes budgétaires, je ne pouvais obtenir qu'un seul Rasberry Pi, j'ai donc décidé de comparer les données de mesure avec les données de l'Agence météorologique près de chez moi. Fait.
Le grattage est l'extraction d'informations spécifiques à partir d'un site Web. Cliquez ici pour plus de détails (https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3 Veuillez cocher% 83% AC% E3% 82% A4% E3% 83% 94% E3% 83% B3% E3% 82% B0).
Mesurez la température et l'humidité avec Raspberry Pi et DHT11 et Créez un enregistreur de température et d'humidité avec Raspberry Zero et DHT11 / items / 2737749d4532150026ee) J'ai construit un circuit et créé un exemple de script en référence à.
J'ai utilisé Raspberry Pi 3B +, et le circuit ressemble à ceci.
Pour chaque fonction de l'exemple de script, [Description détaillée du capteur de température et d'humidité (DHT11)](https://www.souichi.club/technology/dht11-datasheet/#parsedatapulluplengths%E3%83%A1%E3%82%BD Compris en% E3% 83% 83% E3% 83% 89).
Les données de l'Agence météorologique étant grattées, il est nécessaire de faire correspondre l'heure des données à gratter avec les données acquises par le capteur.
La gestion des erreurs étant effectuée par collect_input et parse_data_pull_up_lengths de l'exemple de script, le example.py de l'exemple de script a été réécrit afin que les données mesurées puissent être enregistrées dans le fichier csv. De plus, il semble que la fonction is_varlid () soit exécutée pour vérifier si elle a été obtenue correctement, mais il y a pas mal de cas où cette fonction renvoie un échec.
Quand j'ai eu le nombre d'échecs avec la variable count, ・ Succès en une fois ... 70% ・ Réussi à la 17e fois ... 15% ・ Réussi à la 33e fois ... 10% ・ Plus ... 5% (Je suis désolé. Je n'ai pas de statistiques. C'est juste subjectif.) S'il échoue, il semble qu'il ait échoué dans une rangée de 2 à la nième puissance. Étant donné que les données sont acquises une fois toutes les 60 minutes cette fois, «le nombre d'essais pouvant être pris en compte à partir du nombre d'échecs dans le passé» est fixé à 2 plus 10 (= 1029).
import RPi.GPIO as GPIO
import dht11
import time
import datetime
import os
import numpy as np
import pandas as pd
def add_data(filepath):
#Vérifiez si le fichier csv existe dans le chemin spécifié
if os.path.isfile(filepath):
#Lire s'il existe
df = pd.read_csv(filepath, index_col=0)
else:
#Créer un nouveau s'il n'existe pas
df = pd.DataFrame([], columns=["year","month","day","hour","sensor_temprature", \
"scraping_temprature","read_try"])
#Créez une variable pour compter le nombre de tentatives
count=0
# is_valid()Lire les données de température jusqu'à 1029 fois jusqu'à ce que la fonction soit vraie
while count<=1029:
result = instance.read()
count+=1
if result.is_valid():
#Stocker l'année, le mois et le jour dans DataFrame pour le web scraping
year = datetime.datetime.now().year
month = datetime.datetime.now().month
day = datetime.datetime.now().day
hour = datetime.datetime.now().hour
temp = result.temperature
hum = result.humidity
data=[year,month,day,hour,temp,hum,"",count]
s = pd.Series(data, index=df.columns)
df = df.append(s, ignore_index=True)
break
return df
# initialize GPIO
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
instance = dht11.DHT11(pin=14)
filepath = '/home/pi/Desktop/DHT11_Python/data.csv'
df=add_data(filepath)
df.to_csv(filepath)
print(df)
Je l'ai configuré pour démarrer à l'heure en faisant référence à Exécuter automatiquement les programmes en utilisant systemd sur Raspberry Pi. En outre, Pages de manuel Arch (SYSTEMD.TIME (7)) Défini selon "toutes les heures" en bas Faire.
J'ai écrit le code pour pouvoir gratter les données de l'Agence météorologique, en me référant à Gratter les données météorologiques passées avec Python. Le point à noter est que la méthode de description change légèrement en fonction de la version de la belle soupe et de la tarte à la râpe / pip.
La différence entre l'URL de référence et la page ciblée pour le scraping cette fois est
Capture d'écran de cette cible de scraping
Captures d'écran des liens à gratter
D'autres changements dans l'écriture du code sont
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
import requests
import datetime
import os
import sys
#La modification des codes préc et bloc changera la région.
# m_prec=44 représente Tokyo, m_block=1133 représente Fuchu.
def scraping_weather(m_year,m_month,m_day,m_prec=44,m_block=1133):
url ="https://www.data.jma.go.jp/obd/stats/etrn/view/hourly_a1.php?prec_no={prec}&block_no={block}&year={year}&month={month}&day={day}&view="
url = url.format(prec=m_prec,block=m_block,year=m_year,month=m_month,day=m_day)
html=requests.get(url)
soup = BeautifulSoup(html.content, "html.parser")
# id='tablefix2'de<table>Extrait
table = soup.find('table', id='tablefix1')
#Extraire tout le contenu du tableau 2
th_all = table.find_all('th')
#Stocker manuellement les titres des colonnes
table_column = ["Temps", "Précipitation","Température", "Vitesse / direction du vent(m/s)","日照Temps間","neige(cm)","vitesse du vent","Direction du vent","降neige","積neige"]
# <table>Extraire tout très en.
tr_all = table.find_all('tr')
#Le premier tr est déjà extrait, alors sautez-le
tr_all = tr_all[1:]
#Calculez le nombre de lignes et de colonnes et créez un ndarray
number_of_cols = len(table_column)
number_of_rows = len(tr_all)
table_data = np.zeros((number_of_rows, number_of_cols), dtype=np.float32)
#Stockez les données de chaque ligne dans ndarray
for r, tr in enumerate(tr_all):
td_all = tr.find_all('td')
for c, td in enumerate(td_all):
try:
table_data[r,c] = td.string
except ValueError:
table_data[r,c] = np.nan
#Générer un DataFrame des données extraites
df = pd.DataFrame(data=table_data, columns=table_column)
return df
def combine_scraping_data(df):
date_before=str(0)
#Explorer toutes les données
for i in range(len(df)):
#Vérifier si le web scraping a été effectué dans le passé
if np.isnan(df.loc[i,"scraping_temprature"]):
year = df.loc[i,"year"]
month = df.loc[i,"month"]
day = df.loc[i,"day"]
#Il n'y a pas de données de grattage pour aujourd'hui, alors ignorez si elles sont les mêmes qu'aujourd'hui
if ((day == datetime.date.today().day)&(month == datetime.date.today().month)):
continue
#Remplacer la date par le type str
date_now = str(year)+str(month)+str(day)
#Vérifiez si la ligne et la date précédentes ont changé
if date_now != date_before:
#S'il a changé, grattez-le et stockez-le dans le DataFrame.
t_df = scraping_weather(year,month,day)
# date_Mettre à jour la date de la variable avant
date_before=date_now
for j in range(len(t_df)):
#Faites correspondre les données grattées avec les données du capteur et remplacez la température grattée
if df.loc[i,"hour"] == t_df.loc[j,"Temps"]:
df.loc[i,"scraping_temprature"] = t_df.loc[j,"Température"]
return df
filepath = '/home/pi/Desktop/DHT11_Python/data.csv'
if os.path.isfile(filepath):
df = pd.read_csv(filepath, index_col=0)
else:
print("No data. This python wll be stopped.")
sys.exit()
for i in range(len(df)):
if df.loc[i,'hour']==0:
df.loc[i,'hour'] =24
df.loc[i,'day'] -=1
df = combine_scraping_data(df)
df.to_csv(filepath)
print(df['scraping_temprature'])
Créez un graphique de données de scraping avec matplotlib et enregistrez-le dans le fichier spécifié. Le graphique est [Tracez un graphique linéaire avec matplotlib](https://pythondatascience.plavox.info/matplotlib/%E6%8A%98%E3%82%8C%E7%B7%9A%E3%82%B0%E3% Il a été tracé en référence à 83% A9% E3% 83% 95).
J'ai décidé de créer un dossier pour chaque date dans le dossier de résultats et d'y stocker le fichier csv et le graphique (fichier png). Cela ressemble à ceci sur la figure.
├── creating_graph.py
└── result
├── 6_10
│ ├── 6_10.csv
│ └── 6_10.png
└── 6_11
├── 6_11.csv
└── 6_11.png
De plus, après avoir créé le graphique, j'ai décidé de supprimer les données cibles des données d'origine.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
filepath = '/home/pi/Desktop/DHT11_Python/data.csv'
#Lire le fichier csv avec DataFrame
if os.path.isfile(filepath):
df = pd.read_csv(filepath, index_col=0)
else:
print("No data. This python wll be stopped.")
sys.exit()
#Puisqu'un graphique quotidien est créé, listez les données mois / jour et exécutez une boucle.
for g_month in df["month"].unique():
for g_day in df["day"].unique():
#Données cibles t_Charger dans df
t_df = df[(df['day']==g_day)&(df['month']==g_month)]
#Ignorer si aucune donnée de scraping n'existe
if t_df["scraping_temprature"].isnull().any():
continue
#Créer un nouveau dossier
result_filepath = '/home/pi/Desktop/DHT11_Python/dht11_creating_graph/result/{month}_{day}'
result_filepath = result_filepath.format(month=g_month, day=g_day)
os.makedirs(result_filepath, exist_ok=True)
#Créez et enregistrez le chemin pour enregistrer le fichier csv
result_filename = '/{month}_{day}.csv'
result_filename = result_filename.format(month=g_month, day=g_day)
t_df.to_csv(result_filepath+result_filename)
#Créer un chemin pour stocker le graphique
result_graphname = '/{month}_{day}.png'
result_graphname = result_graphname.format(month=g_month, day=g_day)
#Créer un graphique
x=t_df['hour']
y1=t_df['sensor_temprature']
y2=t_df['scraping_temprature']
fig = plt.figure()
p1 = plt.plot(x, y1, linewidth=2)
p2 = plt.plot(x, y2, linewidth=2, linestyle="dashed")
plt.legend((p1[0], p2[0]), ('sensor_temprature', 'scraping_temprature'), loc=2)
plt.xlabel("hour")
plt.ylabel("temprature")
#Enregistrer le graphique
fig.savefig(result_filepath+result_graphname)
#Supprimer les données graphiques des données d'origine
df = df[(df['day']!=g_day)|(df['month']!=g_month)]
#Réindexer les données d'origine
df.reset_index(inplace=True, drop=True)
#Sauvegardez les données originales
df.to_csv(filepath)
Il y a beaucoup de choses à voir, mais j'ai pu obtenir les données de la chambre chaude du 2ème étage le 14 juin et les données de la salle du 1er étage qui n'est pas si chaude le 16 juin. Si vous regardez le graphique ci-dessous, dans le graphique du premier étage, la température ambiante est inférieure à la température grattée de 8h00 à 18h00, tandis que dans le graphique du deuxième étage, la température ambiante est inférieure à la température grattée. Vous pouvez voir que c'est toujours cher.
Graphique de la chambre chaude au 2ème étage
Graphique d'une pièce au premier étage qui n'est pas si chaude
Photo de référence
Il y a des doutes sur les résultats des mesures, mais comme nous avons pu automatiser le grattage des données de température et la création de graphiques dans une certaine mesure, nous allons terminer cette fois. Je vous serais reconnaissant de bien vouloir me contacter si vous avez des inquiétudes!
Recommended Posts