[PYTHON] Simulez la mesure de température avec Raspberry Pi + Flask + SQLite + Ajax

introduction

Lors de la mesure de la température avec Raspberry Pi et de l'acquisition de l'état du capteur avec GPIO, il est pratique de pouvoir déboguer avec le logiciel seul. Par conséquent, j'ai créé un environnement de débogage qui simule l'acquisition de l'état du capteur par mesure de température et GPIO et l'affiche sur le site Web (créé avec Flask). Enregistrez la température simulée et l'état du capteur dans SQLite et actualisez la page via Ajax. Comme il est difficile de comprendre les valeurs numériques de la température et de l'état du capteur, il semble que la température du salon et du capteur ait changé.

sensor_off.png

Aucune maquette ou câblage n'est requis dans cet environnement. Il ne convient pas à la mesure de température et à l'acquisition de l'état du capteur qui nécessitent des performances en temps réel. Nous supposons un environnement où la température n'a besoin d'être connue qu'à des intervalles de 30 secondes.

Image d'opération

sensor_demo.gif

environnement

Installation

Environnement Python

$ mkdir Sensor
$ cd Sensor
$ pipenv install --python 3.7.2
$ pipenv install flask
$ pipenv install sqlalchemy
$ pipenv shell

Structure des dossiers et des fichiers

--Créez les dossiers et fichiers suivants. --jQuery télécharge la version appropriée depuis jQuery. --Téléchargez l'icône de la flèche (On / Off) à partir de [Free Icon] Flèche (haut / bas / gauche / droite).

└ Sensor/
  ├ server.py
  ├ app/
  │ ├ app.py
  │ └ static/
  │ │ ├ css/
  │ │ │ └ sample.css
  │ │ ├ img/
  │ │ │ ├ arrow_on.png        #Flèche quand elle est allumée
  │ │ │ ├ arrow_off.png       #Flèche quand elle est désactivée
  │ │ │ └ bg_house_living.jpg #image de fond
  │ │ ├ jquery/
  │ │ │ └ jquery-3.4.1-min.js
  │ │ └ js/
  │ │   └ sample.js
  │ └ templates/
  │   └ index.html
  ├ models/                   #Définition SQLite3
  │ ├ __init__.py
  │ ├ database.py
  │ └ models.py
  └ output_log/               #Dossier du journal d'exécution en arrière-plan

Code source

Traitement principal du serveur

--Init_db () initialise la base de données. (Uniquement exécuté si le fichier * .db n'existe pas)

server.py


# -*- coding: utf-8 -*-

from flask import Flask
from app.app import app
from models.database import init_db

if __name__ == "__main__":
    #Initialisation de la base de données
    init_db()
    #Lancez l'appli(host=0,0,0,0 pour toutes les autorisations)
    app.run(host='0.0.0.0', debug=True)

Traitement de simulation de température et de capteur

(référence) Comment exécuter en Python à intervalles réguliers et vérification

sensor.py


# -*- coding: utf-8 -*-

import time
import threading
import random
from models.models import SensorCurrent
from models.database import db_session
from datetime import datetime

#Traitement d'exécution périodique
def schedule():
    #Simulation de température(25 degrés+α)
    now = time.time()
    temp = 25 + now % 5 + (now / 10) % 10
    #Tronquer au deuxième chiffre
    str = "{0:.2f}".format(temp)
    temp = float(str)
    
    #Simulation de l'état du capteur(0 or 1)
    sensor = random.randint(0, 1)

    #Mise à jour actuelle des données
    current = SensorCurrent.query.first()
    current.temp1 = temp
    current.sensor1 = sensor
    db_session.commit()
    db_session.close()

#Traitement périodique des paramètres d'exécution
def scheduler(interval, f, wait = True):
    base_time = time.time()
    next_time = 0
    while True:
        t = threading.Thread(target = f)
        t.start()
        if wait:
            t.join()
        next_time = ((base_time - time.time()) % interval) or interval
        time.sleep(next_time)

if __name__ == "__main__":
    #Paramètre d'exécution périodique(3 secondes d'intervalle)
    scheduler(3, schedule, True)

Traitement principal de l'application

/app/app.py


# -*- coding: utf-8 -*-

from flask import Flask,render_template,request, json, jsonify
from models.models import SensorCurrent

app = Flask(__name__)

#Traitement de l'affichage du site Web
@app.route("/")
def index():
    #Obtenez les données de température et de capteur actuelles de SQlite
    data = SensorCurrent.query.first()
    return render_template("index.html",sensor=data)

#Traitement Ajax
@app.route("/currdata", methods=['POST'])
def getCurrData():
    #Obtenez les données de température et de capteur actuelles de SQlite
    data = SensorCurrent.query.first()
    #Convertir en JSON et renvoyer le résultat
    json_data = {
        'sensor1': data.sensor1,
        'temp1': data.temp1
    }
    return jsonify(Result=json.dumps(json_data))

if __name__ == "__main__":   
    app.run(debug=True)

Définition de la base de données

--Définissez la base de données SQLite3 (sensor.db).

models/database.py


# -*- coding: utf-8 -*-

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import os

#Paramètres du fichier de base de données
databese_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'sensor.db')
engine = create_engine('sqlite:///' + databese_file, convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

#Initialisation de la base de données
def init_db():
    import models.models
    Base.metadata.create_all(bind=engine)

définition de table

--Définissez le tableau des données de température et de courant (currdata) du capteur.

models/models.py


# -*- coding: utf-8 -*-

from sqlalchemy import Column, Integer, Float, String, Text, DateTime
from models.database import Base
from datetime import datetime

#Définition du tableau de données actuel pour la température et le capteur
#Voici une donnée de température,Enregistrer les données d'un capteur
#Veuillez définir la définition de la table comme il convient
class SensorCurrent(Base):
    __tablename__ = 'currdata'
    id = Column(Integer, primary_key=True)
    name = Column(String(128))
    temp1 = Column(Float)
    sensor1 = Column(Integer)
    date = Column(DateTime, default=datetime.now())

    def __init__(self, name=None, temp1=None, sensor1=None, date=None):
        self.name = name
        self.temp1 = temp1
        self.sensor1 = sensor1
        self.date = date

    def __repr__(self):
        return '<Name %r>' % (self.name)

Page principale utilisant Flask

app/templates/index.html


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>{{sensor.name}}</title>
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="stylesheet" type="text/css" href="../static/css/sample.css">
        <script src="../static/jquery/jquery-3.4.1.min.js"></script>
        <script src="../static/js/sample.js"></script>
    </head>
    <body>
    <h1 id="h1_temp1">Temp : {{sensor.temp1}}</h1>
    <h1 id="h1_sensor1">Sensor : {{sensor.sensor1}}</h1>
    
    <div class="sample-box">
        <img class="sample-box-bg" src="../static/img/bg_house_living.jpg " alt="">
        <div class="sample-sensor">
            <img class="sample-sensor-img" id="sensor1" src="../static/img/arrow_off.png " alt="">
        </div>
        <div id="temp1" class="sample-tempareture">
        </div>
    </div>
    </body>
    <script>
        setInterval(function () {
           	getcurrdata();
        }, 2000);
    </script>
</html>

Processus d'acquisition de données actuel

app/static/js/sample.js


//Acquisition de données actuelle
function getcurrdata() {
    $.ajax({
        type: 'POST',
        url: '/currdata',
        data: '',
        contentType: 'application/json'
    })
    .done( (data) => {
        //Acquisition de données réussie
        console.log("success");
        //Extraire des données de JSON
        var json_data = JSON.parse(data.Result);
        const sensor1 = json_data.sensor1;
        const temp1 = json_data.temp1;

        //Réglage de la température dans l'image d'arrière-plan
        $("#temp1").html(temp1 + "℃");
        //Réglage de la température(Pour confirmation)
        $("#h1_temp1").html("Temp : " + temp1);

        //Paramètres d'image du capteur
        if (sensor1 == 0) {
            $("#sensor1").attr("src", "../static/img/arrow_off.png ");
        } else {
            $("#sensor1").attr("src", "../static/img/arrow_on.png ");
        }
        //Paramètres du capteur(Pour confirmation)
        $("#h1_sensor1").html("Sensor : " + sensor1);
    })
    .fail( (data) => {
        //Échec de l'acquisition de données
        console.log("error");
    });
}

CSS de la page principale

――Il prend facilement en charge la conception réactive.

app/static/css/sample.css


@charset "utf-8";

@media screen and (min-width: 481px) {
  .sample-box {
    position: relative;
    display:inline-block;
  }
  .sample-box-bg {
  }

  .sample-sensor {
    position: absolute;
    left: 60%;
    top: 5%;
  }
  .sample-sensor-img {
  }

  .sample-tempareture {
    position: absolute;
    top: 35%;
    left: 55%;
    color: RED;
    font-size: 36px;
  }
}

@media screen and (max-width: 480px) {
  .sample-box {
    position: relative;
    display:inline-block;
  }
  .sample-box-bg {
    width: 100%;
  }

  .sample-sensor {
    position: absolute;
    left: 60%;
    top: 5%;
  }
  .sample-sensor-img {
    width: 70%;
    height: 70%;
  }

  .sample-tempareture {
    position: absolute;
    top: 35%;
    left: 55%;
    color: RED;
    font-size: 22px;
  }
}

Mode opératoire

Apprenez de la simulation de la température et des capteurs à l'affichage de sites Web.

Réglez la température et la valeur initiale du capteur

$ python
from models.database import db_session
from models.models import SensorCurrent
data = SensorCurrent("échantillon",25.3, 0)
db_session.add(data)
db_session.commit()
exit()

Commencez à simuler la température et le capteur

#Exécutez dans le dossier suivant
(Sensor) pi@raspberrypi:~/Sensor $

#Exécutez la commande suivante
nohup python sensor.py > ./output_log/out.log &
#Trouvez le processus exécutant python
$ ps aux | grep python
pi       22965  0.7  2.0  32200 19176 pts/2    S    16:43   0:27 python sensor.py

# sensor.tuer le processus py
$ kill -9 (sensor.identifiant de processus py->22965 ici)

Démarrez le serveur Web

#Exécutez dans le dossier suivant
(Sensor) pi@raspberrypi:~/Sensor $

#Exécutez la commande suivante
python server.py

Afficher la confirmation

sensor_on.png

en conclusion

Si vous souhaitez essayer l'IoT avec Raspberry Pi, mais que vous développez du matériel en même temps, ou si vous ne pouvez pas préparer une maquette ou un câblage, vous pouvez facilement le simuler. La température et le nombre de capteurs peuvent être librement conçus selon la définition de SQLite, je vais donc l'utiliser à partir de maintenant.

référence

Je me suis référé au site suivant. Les développeurs d'applications Web inexpérimentés utiliseront Flask, SQLite et Heroku pour lancer le service dans une semaine Démarrez un serveur Web avec Raspberry pi + Nginx + uWSGI et essayez de déployer l'application Django, partie 1 Comment exécuter en Python à intervalles réguliers et vérification Gagnez du temps avec l'exécution en arrière-plan! !!

Recommended Posts

Simulez la mesure de température avec Raspberry Pi + Flask + SQLite + Ajax
Obtenez la température et l'humidité avec DHT11 et Raspberry Pi
Mesurer la température du processeur de Raspeye avec Python
GPGPU avec Raspberry Pi
DigitalSignage avec Raspberry Pi
Enregistrez la température et l'humidité avec systemd sur Raspberry Pi
Mesurez la température et l'humidité avec Raspberry Pi3 et visualisez avec Ambient
Plantes Mutter avec Raspberry Pi
Mesurez et comparez les températures avec Raspberry Pi et générez automatiquement des graphiques
[Raspberry Pi] Contrôle du moteur pas à pas avec Raspberry Pi
Utilisez vl53l0x avec RaspberryPi (python)
Commande de servomoteur avec Raspberry Pi
Communication série avec Raspberry Pi + PySerial
Notifier LINE de la température corporelle du thermomètre BLE avec la tarte à la râpe # 1
Configuration du système d'exploitation avec Raspberry Pi Imager
Avertir LINE de la température corporelle du thermomètre BLE avec la tarte à la râpe n ° 2
Essayez L Chika avec raspberrypi
Construire un serveur VPN avec Raspberry Pie
Essayez de déplacer 3 servos avec Raspeye
Utiliser une webcam avec Raspberry Pi
Production d'un système de contrôle de température avec tarte aux framboises et ESP32 (2) Production d'un appareil de transmission
Surveillance des animaux avec Rekognition et Raspberry pi
Créer un environnement Tensorflow avec Raspberry Pi [2020]
Essayez de pêcher le Wakasagi avec Raspberry Pi
Programmation normale avec la programmation Node-RED avec Raspberry Pi 3
Essayez la détection d'objets avec Raspberry Pi 4 + Coral
Exécuter le servomoteur SG-90 avec Raspberry Pi
Travailler avec des capteurs dans Mathematica sur Raspberry Pi
Utiliser le capteur de mouvement PIR avec Raspberry Pi
Faire une minuterie de lavage-séchage avec Raspberry Pi
Modèle Infer Custom Vision avec Raspeye
Faites fonctionner l'oscilloscope avec le Raspberry Pi
Créez un compteur de voiture avec Raspberry Pi
Enregistrement de la valeur d'Inkbird IBS-TH1 avec Raspberry Pi
Travailler avec le GPS en Python pour Raspberry Pi 3
Création d'un système de contrôle de température avec tarte aux framboises et ESP32 (3) Réception d'un fichier Python
Discord bot raspberry pi zéro avec python [Note]
Programmation média avec Raspeye (préparation audio)
J'ai essayé L-Chika avec Razpai 4 (édition Python)
Profitez du travail électronique avec GPIO de Raspberry Pi
MQTT Radicon Car avec Arduino et Raspberry
Allumez / éteignez votre PC avec Raspberry Pi
Sortie CSV des données d'impulsion avec Raspberry Pi (sortie CSV)
Observez le groupe de météores Futago avec RaspberryPi4
Obtenez des informations sur le processeur de Raspberry Pi avec Python
Afficher la température du processeur toutes les 5 secondes sur Raspberry Pi 4
Envoyer msgpack avec ajax à l'environnement flask (werkzeug)
Raspberry + am2302 Mesure la température et l'humidité avec un capteur de température et d'humidité
Application d'analyse des investissements boursiers avec tarte aux framboises
Enregistrement de la valeur d'Inkbird IBS-TH1 mini avec Raspberry Pi
Connectez-vous à MySQL avec Python sur Raspberry Pi
Suivi GPS avec Raspeye 4B + BU-353S4 (Python)