Les capteurs environnementaux d'Omron incluent la température, l'humidité, l'éclairement, la pression, le bruit, etc. Un appareil qui combine plusieurs capteurs ensemble Les fonctions complètes typiques des fabricants de capteurs sont attrayantes! (Gauche: BAG type 2JCIE-BL01, Droite: USB type 2JCIE-BU01)
Dans cet article, nous obtiendrons la valeur du capteur environnemental de RaspberryPi. Je l'ai téléchargé dans une feuille de calcul Google.
Essayez-le, de la détection à la journalisation ** Les fonctions jusqu'à présent peuvent-elles être réalisées avec uniquement un équipement universel bon marché? ** ** Je suis surpris. (Au lieu de cela, il y a beaucoup de points addictifs qui me donnent l'impression que je vais me briser le cœur, mais lol)
** ・ RaspberryPi ** (Pi3 Model B est utilisé cette fois) ** - Environnement d'exécution Python ** (Cette fois, pyenv utilise Python 3.7.6) ** ・ Compte Google ** (requis pour utiliser des feuilles de calcul) ** ・ Smartphone ** (pour le réglage du scanner BLE) ** ・ Capteur environnemental Omron (type BAG) ** * Un article distinct sera créé pour le type USB.
** ① Vérifiez la connexion Bluetooth entre le Raspberry Pi et le capteur ** ** ② Changez le mode du capteur d'environnement sur Broadcaster ** ** ③ Obtenez la valeur mesurée du capteur d'environnement avec Python ** ** ④ Accédez à l'API GAS de Python pour écrire des données dans la feuille de calcul ** ** ⑤ Exécution périodique du script **
Fondamentalement, Raspberry Pi est le point de départ (central) du traitement.
** ・ Vérifiez le fonctionnement du capteur d'environnement ** Insérez la batterie et vérifiez que la lampe s'allume pendant un moment.
** - Recherche d'appareils Bluetooth ** Exécutez la commande suivante sur Raspberry Pi
sudo hcitool lescan
LE Scan ...
DD:CC:BB:AA:77:66 Env
Lorsque le nom «Env» apparaît, il s'agit de l'adresse MAC du capteur d'environnement. S'il ne sort pas, vérifiez le contact de la batterie et l'activation Bluetooth du Raspberry Pi.
bluepy est une bibliothèque pour accéder à Bluetooth Low Energy (BLE) en Python (Définition de classe)
Ici, vérifiez si bluepy peut reconnaître le capteur d'environnement.
** ・ Installation des packages requis ** Installez ce qui suit
sudo apt install libglib2.0-dev
** ・ Installation de bluepy **
Installer avec pip avec la commande suivante
pip install bluepy
** ・ Autoriser bluepy ** Vous devez autoriser bluepy Sudo à scanner.
Allez dans le dossier où bluepy est installé et
cd ~.pyenv/versions/3.7.6/lib/python3.7/site-packages/bluepy
Accordez l'autorisation Sudo à bluepy-helper avec la commande suivante
sudo setcap 'cap_net_raw,cap_net_admin+eip' bluepy-helper
** - Création d'un code de numérisation ** Créez le code ci-dessous
ble_scan.py
from bluepy import btle
class ScanDelegate(btle.DefaultDelegate):
def __init__(self): #constructeur
btle.DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData): #Gestionnaire de scan
if isNewDev: #Lorsqu'un nouvel appareil est trouvé
print('found dev (%s)' % dev.addr)
scanner = btle.Scanner().withDelegate(ScanDelegate())
while True:
scanner.scan(10.0)
Le code ci-dessus fonctionne, Ce qui est important c'est ** Classe de scanner ** ** Classe DefaultDelegate ** ** Classe ScanEntry ** est.
Dans le code ci-dessus ** - Méthode Scanner.scan: ** Définissez l'argument (10 secondes dans le cas ci-dessus) comme valeur de délai d'expiration et exécutez le délégué spécifié par la méthode Scanner.withDelegate. ** - Classe DefaultDelegate: ** Classe d'héritage pour la création d'un délégué pour l'argument de Scanner.withDelegate. Décrire le traitement spécifique dans la méthode handleDiscovery ** - Classe ScanEntry: ** Contient les informations de périphérique acquises par Scanner.scan. L'argument "dev" de handleDiscovery est équivalent En utilisant,
** "Définissez 10 secondes comme valeur de délai d'expiration et continuez d'afficher l'adresse Mac du périphérique nouvellement trouvé" **.
** ・ Exécution du code de numérisation **
python ble_scan.py
Comme indiqué ci-dessous, si la même adresse MAC que dans LE Scan sort, cela réussit. (Notez que l'adresse MAC est inférieure)
found dev (dd:cc:bb:aa:77:66)
Avec ce qui précède, nous avons confirmé la reconnaissance du capteur environnemental dans bluepy.
Comme décrit dans cet article, Pour la transmission de données (publicité) des appareils BLE ** ・ Mode de connexion: ** Acquérir des données par communication bidirectionnelle ** - Diffuseur: ** Transmission de données unilatérale de l'appareil au central Il existe deux types, ** Le diffuseur est avantageux en termes de consommation d'énergie **. (À l'inverse, le mode de connexion permet des opérations compliquées pour modifier les paramètres de l'appareil)
Pour augmenter la durée de fonctionnement du capteur d'environnement alimenté par batterie Changez pour Broadcaster et procédez aux opérations suivantes
Un outil appelé BLE Scannear utilisé pour changer le mode Veuillez installer sur votre smartphone à partir des éléments suivants Android iOS
Modifiez les paramètres de publicité et définissez le mode sur Diffuseur. Vous pouvez également modifier ici l'intervalle de transmission de la publicité (pour les applications nécessitant de la vitesse)
** - Ouvrez le scanner BLE et connectez-vous à l'appareil étiqueté «Env» **
** ・ "0C4C3042 ~" est le paramètre de publicité, alors cherchez-le **
** ・ Comment lire les paramètres de publicité dans (2) ci-dessus ** Si vous lisez le Manuel de l'utilisateur officiel d'Omron, il ressemblera à l'illustration ci-dessous. ** ・ Si vous souhaitez passer en mode diffusion: réglez le mode balise sur 02 ou 04 ** ** ・ Si vous souhaitez raccourcir l'intervalle de mise à jour: réduisez l'intervalle de transmission de la publicité ** Il faut changer.
Le mode Beacon se demande s'il est 02 ou 04, Cette fois, nous nous concentrerons sur l'indice environnemental Before:0808A0000A003200 08 00 After:0808A0000A003200 04 00 ça ira. (Si vous utilisez un capteur d'accélération, réglez-le sur 02)
** ・ Modifier les paramètres de publicité ** Cliquez sur ③ «W» dans la figure ci-dessus, modifiez-le comme indiqué dans la figure ci-dessous et appuyez sur OK.
** ・ Confirmation de changement ** Si vous revenez en haut et que le nom de l'appareil passe à "EP", vous avez réussi.
L'intervalle de mise à jour par défaut des valeurs de capteur est de 300 secondes (5 minutes). C'est trop long! Je pense qu'il y a beaucoup de monde, je vais donc le changer brièvement.
** ・ "0C4C3011 ~" est le paramètre d'intervalle de mise à jour, alors cherchez-le ** Après l'opération précédente, connectez-vous à l'appareil BLE Scanner "EP" et Recherchez "0C4C3011 ~"
** ・ Comment lire le paramètre d'intervalle de mise à jour dans (2) ci-dessus ** C'est l'intervalle de mise à jour en secondes converti en hexadécimal. Cependant, comme il s'agit d'une spécification qui pleure pour les débutants, l'octet supérieur et l'octet inférieur sont inversés ** Faites attention. Cette fois, entrez "0A00" pour changer l'intervalle à 10 secondes comme indiqué dans la figure ci-dessous.
** ・ Confirmation du changement de l'intervalle de mise à jour ** Si vous appuyez sur "R" et que le contenu de Hex est mis à jour, cela réussit.
Si vous cliquez sur "RAW DATA" sur l'écran supérieur, vous pouvez voir les valeurs mesurées du capteur.
Les spécifications des valeurs mesurées sont indiquées dans la figure ci-dessous.
Puisqu'il a été constaté que la valeur mesurée du capteur peut être obtenue en (2), Augmentez la polyvalence du traitement avec Python.
Créez une classe pour obtenir des mesures de capteurs avec bluepy. Comme pour ① et time, car le traitement au moment de la numérisation est passé en tant que délégué Créez un code comme celui ci-dessous.
La valeur de mesure de capteur acquise est enregistrée sous forme de dict pour chaque type de capteur dans la variable «sensorValue».
omron_env_broadcast.py
from bluepy import btle
import time
import struct
class ScanDelegate(btle.DefaultDelegate):
#constructeur
def __init__(self):
btle.DefaultDelegate.__init__(self)
#Variables pour conserver les données du capteur
self.sensorValue = None
#Gestionnaire de scan
def handleDiscovery(self, dev, isNewDev, isNewData):
#Lorsqu'un nouvel appareil est trouvé
if isNewDev or isNewData:
#Extraire les données publicitaires
for (adtype, desc, value) in dev.getScanData():
#Effectuer la récupération des données lorsque le capteur d'environnement
if desc == 'Manufacturer' and value[0:4] == 'd502':
#Retirez le type de capteur (EP ou IM)
sensorType = dev.scanData[dev.SHORT_LOCAL_NAME].decode(encoding='utf-8')
#Extraction des données du capteur pendant EP
if sensorType == 'EP':
self.decodeSensorData_EP(value)
#Extraction des données du capteur pendant la messagerie instantanée
if sensorType == 'IM':
self.decodeSensorData_IM(value)
#Extraire les données du capteur et les convertir au format dict (en mode EP)
def decodeSensorData_EP(self, valueStr):
#Données du capteur de la chaîne de caractères(6ème et suivants caractères)Sortir et convertir uniquement en binaire
valueBinary = bytes.fromhex(valueStr[6:])
#Convertir les données binaires du capteur en nombre entier Taple
(temp, humid, light, uv, press, noise, discomf, wbgt, rfu, batt) = struct.unpack('<hhhhhhhhhB', valueBinary)
#Stocker dans le type de dict après la conversion d'unité
self.sensorValue = {
'SensorType': 'EP',
'Temperature': temp / 100,
'Humidity': humid / 100,
'Light': light,
'UV': uv / 100,
'Pressure': press / 10,
'Noise': noise / 100,
'Discomfort': discomf / 100,
'WBGT': wbgt / 100,
'BatteryVoltage': (batt + 100) / 100
}
#Extraire les données du capteur et les convertir au format dict (en mode IM)
def decodeSensorData_IM(self, valueStr):
#Données du capteur de la chaîne de caractères(6ème et suivants caractères)Sortir et convertir uniquement en binaire
valueBinary = bytes.fromhex(valueStr[6:])
#Convertir les données binaires du capteur en nombre entier Taple
(temp, humid, light, uv, press, noise, accelX, accelY, accelZ, batt) = struct.unpack('<hhhhhhhhhB', valueBinary)
#Stocker dans le type de dict après la conversion d'unité
self.sensorValue = {
'SensorType': 'IM',
'Temperature': temp / 100,
'Humidity': humid / 100,
'Light': light,
'UV': uv / 100,
'Pressure': press / 10,
'Noise': noise / 100,
'AccelerationX': accelX / 10,
'AccelerationY': accelY / 10,
'AccelerationZ': accelZ / 10,
'BatteryVoltage': (batt + 100) / 100
}
#Effectuer la récupération des données lorsque le capteur d'environnement
if desc == 'Manufacturer' and value[0:4] == 'd502':
#Retirez le type de capteur (EP ou IM)
sensorType = dev.scanData[dev.SHORT_LOCAL_NAME].decode(encoding='utf-8')
#Extraction des données du capteur pendant EP
if sensorType == 'EP':
self.decodeSensorData_EP(value)
#Extraction des données du capteur pendant la messagerie instantanée
if sensorType == 'IM':
self.decodeSensorData_IM(value)
Le processus ci-dessus a été créé sur la base des éléments suivants. ・ Le capteur environnemental peut être identifié par "desc = 'Fabricant' et la valeur 0-4ème caractère est'd502 '" -Le mode et les valeurs mesurées du capteur sont conservés sous la forme illustrée dans la [Référence] suivante. -Comme la valeur de mesure acquise est constituée de données binaires et que le format diffère selon que le mode est EP ou IM, créez une méthode "decodeSensorData" pour chaque mode afin de le convertir au format numérique Dict pour une facilité d'utilisation.
** [Référence] Résultats du débogage des données de publicité en mode BroadCast avec VS Code **
Créez le code principal pour exécuter la classe d'acquisition de valeur de capteur ci-dessus. Définissez la classe d'acquisition de la valeur du capteur dans le délégué du scanner comme dans (2) et définissez-la. Scannez et exécutez.
omron_env_toSpreadSheet.py
from bluepy import btle
from omron_env_broadcast import ScanDelegate
#omron_env_broadcast.Définit le délégué d'acquisition de la valeur du capteur de py pour qu'il s'exécute au moment du scan
scanner = btle.Scanner().withDelegate(ScanDelegate())
#Scan pour obtenir la valeur du capteur (délai d'attente 5 secondes)
scanner.scan(5.0)
#Afficher la température à titre d'essai
print(scanner.delegate.sensorValue['Temperature'])
#Décrivez le processus de téléchargement vers la feuille de calcul Google dans ④
Essayez de courir à partir de la console
python omron_env_toSpreadSheet.py
25.98
Vous avez maintenant obtenu des mesures de capteurs en Python. La valeur de mesure acquise est stockée dans scanner.delegate.sensorValue.
Exportez les données acquises dans une feuille de calcul Google.
** * La plupart des gens souhaitent produire des résultats autres que des feuilles de calcul, donc ** ** Dans ce cas, sautez ce chapitre et passez à ⑤ ** (Il existe de nombreuses options telles que la sortie CSV avec Pandas et la visualisation avec Ambient)
Effectuez ce travail sur votre PC.
Accédez à Google Spreadsheets et accédez à Créez une feuille de calcul comme celle ci-dessous Notez que ** le nom de la feuille doit être le même que le nom de l'appareil **
Sélectionnez "Outils" -> "Éditeur de script" Créez un script GAS comme celui ci-dessous
postSensorData.gs
var spreadsheetId = '******'//← Entrez l'ID de la feuille de calcul
//Recevoir les données publiées
function doPost(e){
var data = [
e.parameter.Date_Master, //Date et heure principales
e.parameter.Date, //Date et heure de la mesure
e.parameter.Temperature, //Température
e.parameter.Humidity, //Humidité
e.parameter.Light, //Éclairage
e.parameter.UV, // UV
e.parameter.Pressure, //pression
e.parameter.Noise, //bruit
e.parameter.BatteryVoltage, //Voltage de batterie
new Date(), //Heure de fin du téléchargement
];
//Décrivez les données acquises dans le journal
Logger.log(new Date());
//Écrire une ligne de données dans une feuille de calcul
addData(e.parameter.DeviceName, data);
return ContentService.createTextOutput("ok");
}
//Écrire une ligne de données dans une feuille de calcul
function addData(sheetName, data){
var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
sheet.appendRow(data);
}
** * Apparemment, le nom de la fonction doit être "doPost" pour publier à l'aide de l'API **
https://docs.google.com/spreadsheets/d/AAAAAAA/edit
Si tel est le cas, la partie "AAAAAAA" correspond
"Publier" → "Introduit en tant qu'application Web"
L'écran suivant apparaîtra, donc ・ Version du projet → Version que vous souhaitez convertir en API (sélectionnez d'abord "Nouveau") ・ Exécutez l'application en tant que → Moi (soi-même) ・ Qui a accès à l'application → Tout le monde, même anonyme (tous (y compris les utilisateurs anonymes)) Sélectionnez pour mettre à jour (déployer)
En cas de succès, l'écran suivant apparaîtra. Notez l'URL de l'API car vous l'utiliserez plus tard.
** * A partir de là, le travail se fera côté Raspberry Pi ** Appuyez sur l'API avec curl pour envoyer les données appropriées et testez si le POST peut être effectué de l'extérieur. Exécutez la commande suivante (installez curl s'il n'est pas inclus)
curl -L [URL de l'API] -F 'sheetName=[Nom de la feuille]' -F "Date_Master=4.1" -F "Date=4.2" -F "SensorType=4.2" -F "Temperature=4.4" -F "Humidity=4.4" -F "Light=4.1" -F "UV=4.2" -F "Pressure=4.4" -F "Noise=4.4" -F "BatteryVoltage=4.4" -F "DeviceName=[Nom de la feuille]"
Succès si les valeurs sont entrées dans la feuille de calcul
Installez la bibliothèque Requests pour effectuer le POST côté Python
pip install requests
Dans le code "omron_env_toSpreadSheet.py" créé en ③, Ajoutez un processus pour télécharger des données en appuyant sur l'API du script GAS.
omron_env_toSpreadSheet.py
from bluepy import btle
from omron_env_broadcast import ScanDelegate
from datetime import datetime, timedelta
import requests
#Obtenez l'heure actuelle
date = datetime.today()
#Arrondir l'heure actuelle en minutes
masterDate = date.replace(second=0, microsecond=0)
if date.second >= 30:
masterDate += timedelta(minutes=1)
#omron_env_broadcast.Définit le délégué d'acquisition de la valeur du capteur de py pour qu'il s'exécute au moment du scan
scanner = btle.Scanner().withDelegate(ScanDelegate())
#Scannez pour obtenir la valeur du capteur
scanner.scan(5.0)
######Processus de téléchargement sur la feuille de calcul Google######
#Télécharger uniquement lorsque la valeur du capteur n'est pas Aucune
if scanner.delegate.sensorValue is not None:
#Nom de l'appareil
deviceName = '****'#← Donnez-lui le même nom que le nom de la feuille de calcul
#Données à POST
data = {
'DeviceName': deviceName,
'Date_Master': str(masterDate),
'Date': str(date),
'SensorType': str(scanner.delegate.sensorValue['SensorType']),
'Temperature': str(scanner.delegate.sensorValue['Temperature']),
'Humidity': str(scanner.delegate.sensorValue['Humidity']),
'Light': str(scanner.delegate.sensorValue['Light']),
'UV': str(scanner.delegate.sensorValue['UV']),
'Pressure': str(scanner.delegate.sensorValue['Pressure']),
'Noise': str(scanner.delegate.sensorValue['Noise']),
'BatteryVoltage': str(scanner.delegate.sensorValue['BatteryVoltage'])
}
#URL de l'API
url = 'https://script.google.com/macros/s/******/exec'#← Entrez l'URL de l'API
#POST des données vers l'API
response = requests.post(url, data=data)
Exécutez le script Python ci-dessus avec la commande suivante
python omron_env_toSpreadSheet.py
Comme le montre la figure ci-dessous, si la valeur du capteur est entrée dans la feuille de calcul, cela réussit.
Avec la méthode ci-dessus, il est difficile d'exécuter le script à chaque fois, donc Automatisez en utilisant le package périodique "cron". Cela ressemble à un planificateur de tâches Windows.
Il peut être désactivé par défaut, alors activez-le en vous référant à here.
** ・ Point de contrôle 1: Vérifiez rsyslog.conf ** Cela ne fonctionnera pas si "cron" dans /etc/rsyslog.conf est commenté. Dans mon cas, il a été commenté comme ci-dessous, donc
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
Après avoir décommenté comme ci-dessous,
cron.* /var/log/cron.log
Redémarrez rsyslog avec la commande suivante.
sudo /etc/init.d/rsyslog restart
** ・ Point de contrôle 2: Modifier le niveau de journal ** Dans / etc / default / cron, spécifiez les éléments à décrire dans le journal lorsque cron est exécuté. Par défaut, il semble que le journal ne soit pas sorti comme indiqué ci-dessous, donc
# For quick reference, the currently available log levels are:
# 0 no logging (errors are logged regardless)
# 1 log start of jobs
# 2 log end of jobs
# 4 log jobs with exit status != 0
# 8 log the process identifier of child process (in all logs)
#
#EXTRA_OPTS=""
Supprimer les commentaires de EXTRA_OPTS comme indiqué ci-dessous
EXTRA_OPTS='-L 15'
ça ira. Cela signifie que toutes les sorties sont 1 + 2 + 4 + 8 = 15.
Redémarrez cron avec la commande suivante.
sudo /etc/init.d/cron restart
Il réussit si cron.log est généré dans / var / log. (Veuillez cocher ici si vous voulez voir l'historique d'exécution de cron)
Enregistrer l'exécution périodique avec cron
** - Modifier crontab ** Ouvrez crontab avec la commande suivante
crontab -e
Lorsqu'on vous demande quel éditeur ouvrir, sélectionnez celui que vous aimez (nano recommandé pour les débutants)
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
: Diverses choses continuent
Il y a divers commentaires écrits comme ci-dessus, À la toute fin, décrivez le timing et la commande que vous souhaitez exécuter. Le format de synchronisation est [ici](http://tech.junkpot.net/archives/721/crontab-%E3%81%A7%E7%B4%B0%E3%81%8B%E3%81%84%E3 % 82% B9% E3% 82% B1% E3% 82% B8% E3% 83% A5% E3% 83% BC% E3% 83% AB% E3% 81% AE% E8% A8% AD% E5% AE Veuillez vous référer à% 9A.html)
Cette fois, puisqu'elle est exécutée toutes les 5 minutes, le contenu suivant est décrit.
*/5 * * * * [Chemin complet de Python] [omron_env_toSpreadSheet.chemin complet de py] >/dev/null 2>&1
** ・ Démarrer cron ** Démarrez cron avec la commande suivante
sudo /etc/init.d/cron start
Attendez un peu ci-dessus et si la feuille de calcul est mise à jour toutes les 5 minutes, vous avez terminé!
Augmentez le nombre de capteurs et réalisez la maison IoT de vos rêves! ** Il semble que vous pouvez le faire. Les capteurs Omron sont multifonctionnels et de haute qualité, mais pas assez bon marché pour acheter des pompons, J'essaierai même un capteur moins cher!