[PYTHON] Simulate temperature measurement with Raspberry Pi + Flask + SQLite + Ajax

Introduction

When measuring temperature with Raspberry Pi and acquiring sensor status with GPIO, it is convenient to be able to debug with the software alone. Therefore, I created a debug environment that simulates the acquisition of sensor status by temperature measurement and GPIO and displays it on the website (created with Flask). Save the simulated temperature and sensor state in SQLite and refresh the page via Ajax. Since it is difficult to understand from the values of temperature and sensor status, it looks as if the temperature of the living room and the sensor have changed.

sensor_off.png

No breadboard or wiring is required in this environment. It is not suitable for temperature measurement and sensor status acquisition that require real-time performance. We assume an environment where the temperature only needs to be known at 30-second intervals.

Operation image

--The temperature and sensor status arrows are updated.

sensor_demo.gif

environment

Installation

Python environment

--Here, create a Sensor folder and install the environment with pipenv. --Installation of pipenv and Web server (Nginx, uWSGI, etc.) is omitted.

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

Folder and file structure

--Create the following folders and files. --jQuery downloads the appropriate version from jQuery. --Download the arrow icon (On / Off) from [Free Icon] Arrow (up / down / left / right). --The background can be downloaded from Cute Free Material Collection Irasutoya.

└ Sensor/
  ├ server.py
  ├ app/
  │ ├ app.py
  │ └ static/
  │ │ ├ css/
  │ │ │ └ sample.css
  │ │ ├ img/
  │ │ │ ├ arrow_on.png        #Arrow when on
  │ │ │ ├ arrow_off.png       #Arrow when Off
  │ │ │ └ bg_house_living.jpg #background image
  │ │ ├ jquery/
  │ │ │ └ jquery-3.4.1-min.js
  │ │ └ js/
  │ │   └ sample.js
  │ └ templates/
  │   └ index.html
  ├ models/                   #SQLite3 definition
  │ ├ __init__.py
  │ ├ database.py
  │ └ models.py
  └ output_log/               #Background execution log folder

Source code

Server main processing

--Init_db () initializes the Database. (Only executed if the * .db file does not exist)

server.py


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

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

if __name__ == "__main__":
    #Database initialization
    init_db()
    #Launch the app(host=0,0,0,0 for all permissions)
    app.run(host='0.0.0.0', debug=True)

Temperature and sensor simulation processing

--Simulate temperature and sensor every 3 seconds. --The temperature is simulated at 25 degrees + α. --The sensor simulates with 0 or 1.

(reference) How to execute in Python at regular intervals and verification

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

#Periodic execution processing
def schedule():
    #Temperature simulation(25 degrees+α)
    now = time.time()
    temp = 25 + now % 5 + (now / 10) % 10
    #Truncate to two decimal places
    str = "{0:.2f}".format(temp)
    temp = float(str)
    
    #Sensor state simulation(0 or 1)
    sensor = random.randint(0, 1)

    #Current data update
    current = SensorCurrent.query.first()
    current.temp1 = temp
    current.sensor1 = sensor
    db_session.commit()
    db_session.close()

#Periodic execution setting processing
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__":
    #Periodic execution setting(3 second intervals)
    scheduler(3, schedule, True)

App main processing

--Describe website display and Ajax processing.

/app/app.py


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

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

app = Flask(__name__)

#Website display processing
@app.route("/")
def index():
    #Get current temperature and sensor data from SQlite
    data = SensorCurrent.query.first()
    return render_template("index.html",sensor=data)

#Ajax processing
@app.route("/currdata", methods=['POST'])
def getCurrData():
    #Get current temperature and sensor data from SQlite
    data = SensorCurrent.query.first()
    #Convert to JSON and return the result
    json_data = {
        'sensor1': data.sensor1,
        'temp1': data.temp1
    }
    return jsonify(Result=json.dumps(json_data))

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

Database definition

--Define the SQLite3 database (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

#Database file settings
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()

#Database initialization
def init_db():
    import models.models
    Base.metadata.create_all(bind=engine)

table definition

--Define the temperature and current sensor data table (currdata).

models/models.py


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

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

#Current data table definition for temperature and sensor
#Here is one temperature data,Save one sensor data
#Please set the table definition as appropriate
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)

Main page with Flask

--The current data is acquired and displayed at startup. (The arrow defaults to Off) --Use Ajax to get the current data every 2 seconds and rewrite the page.

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>

Current data acquisition process

--Get the current data using Ajax.

app/static/js/sample.js


//Current data acquisition
function getcurrdata() {
    $.ajax({
        type: 'POST',
        url: '/currdata',
        data: '',
        contentType: 'application/json'
    })
    .done( (data) => {
        //Successful data acquisition
        console.log("success");
        //Extract data from JSON
        var json_data = JSON.parse(data.Result);
        const sensor1 = json_data.sensor1;
        const temp1 = json_data.temp1;

        //Temperature setting in the background image
        $("#temp1").html(temp1 + "℃");
        //Temperature setting(For confirmation)
        $("#h1_temp1").html("Temp : " + temp1);

        //Sensor image settings
        if (sensor1 == 0) {
            $("#sensor1").attr("src", "../static/img/arrow_off.png ");
        } else {
            $("#sensor1").attr("src", "../static/img/arrow_on.png ");
        }
        //Sensor settings(For confirmation)
        $("#h1_sensor1").html("Sensor : " + sensor1);
    })
    .fail( (data) => {
        //Data acquisition failure
        console.log("error");
    });
}

Main page CSS

――It easily supports responsive design.

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;
  }
}

Method of operation

Learn from simulating temperature and sensors to displaying websites.

Set the temperature and the initial value of the sensor

--Initial values of temperature and sensor (only one) are added to the currdata table. --Start python in the Sensor folder and execute the following source code. --You only need to execute it once.

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

Start simulating temperature and sensor

--From the Sensor folder, launch an app that simulates temperature and sensors in the background. --I run it in the background because I want to run it at the same time as the server app.

#Run in the following folder
(Sensor) pi@raspberrypi:~/Sensor $

#Execute the following command
nohup python sensor.py > ./output_log/out.log &

--If you have already started the simulation, kill the process before starting it.

#Find the process running python
$ ps aux | grep python
pi       22965  0.7  2.0  32200 19176 pts/2    S    16:43   0:27 python sensor.py

# sensor.kill py process
$ kill -9 (sensor.py process id->22965 here)

Start the web server

--Start the server main process.

#Run in the following folder
(Sensor) pi@raspberrypi:~/Sensor $

#Execute the following command
python server.py

Display confirmation

--Start your browser and access http://127.0.0.1:5000. --You can also access the local IP address of the web server. ――If you access from a smartphone, I think that the responsive design is simply applied.

sensor_on.png

in conclusion

If you want to try IoT with Raspberry Pi, but you are developing hardware at the same time, or if you can not prepare breadboard and wiring, you can easily simulate it. The temperature and the number of sensors can be freely designed according to the definition of SQLite, so I will utilize it from now on.

reference

I referred to the following site. Inexperienced web application developers use Flask, SQLite, and Heroku to release the service in a week Start a web server with Raspberry pi + Nginx + uWSGI and deploy the Django app Part 1 How to execute in Python at regular intervals and verification Save time with background execution! !!

Recommended Posts

Simulate temperature measurement with Raspberry Pi + Flask + SQLite + Ajax
Get temperature and humidity with DHT11 and Raspberry Pi
Measure CPU temperature of Raspberry Pi with Python
GPGPU with Raspberry Pi
DigitalSignage with Raspberry Pi
Record temperature and humidity with systemd on Raspberry Pi
Measure temperature and humidity with Raspberry Pi3 and visualize with Ambient
Mutter plants with Raspberry Pi
SNS Flask (Ajax) made with Flask
I tried using the DS18B20 temperature sensor with Raspberry Pi
Measure and compare temperature with Raspberry Pi and automatically generate graph
Creating a temperature / humidity monitor with Raspberry Pi (pigpio version)
[Raspberry Pi] Stepping motor control with Raspberry Pi
Use vl53l0x with Raspberry Pi (python)
Servo motor control with Raspberry Pi
Serial communication with Raspberry Pi + PySerial
Notify LINE of body temperature from BLE thermometer with Raspberry Pi # 1
OS setup with Raspberry Pi Imager
Notify LINE of body temperature from BLE thermometer with Raspberry Pi # 2
Try L Chika with raspberry pi
VPN server construction with Raspberry Pi
Try moving 3 servos with Raspberry Pi
Using a webcam with Raspberry Pi
Production of temperature control system with Raspberry Pi and ESP32 (2) Production of transmission device
Pet monitoring with Rekognition and Raspberry pi
Build a Tensorflow environment with Raspberry Pi [2020]
Get BITCOIN LTP information with Raspberry PI
Try fishing for smelt with Raspberry Pi
Programming normally with Node-RED programming on Raspberry Pi 3
Try Object detection with Raspberry Pi 4 + Coral
Power SG-90 servo motor with raspberry pi
Working with sensors on Mathematica on Raspberry Pi
Use PIR motion sensor with raspberry Pi
Make a wash-drying timer with a Raspberry Pi
Infer Custom Vision model with Raspberry Pi
Operate an oscilloscope with a Raspberry Pi
Create a car meter with raspberry pi
Inkbird IBS-TH1 value logged with Raspberry Pi
Working with GPS on Raspberry Pi 3 Python
Creating a temperature control system with Raspberry Pi and ESP32 (3) Recipient Python file
Discord bot with python raspberry pi zero with [Notes]
Media programming with Raspberry Pi (preparation for audio)
I tried L-Chika with Raspberry Pi 4 (Python edition)
Enjoy electronic work with GPIO on Raspberry Pi
MQTT RC car with Arduino and Raspberry Pi
Power on / off your PC with raspberry pi
Use Majoca Iris elongated LCD with Raspberry Pi
CSV output of pulse data with Raspberry Pi (CSV output)
Observe the Geminids meteor shower with Raspberry Pi 4
Get CPU information of Raspberry Pi with Python
Play with your Ubuntu desktop on your Raspberry Pi 4
Display CPU temperature every 5 seconds on Raspberry Pi 4
Send msgpack with ajax to flask (werkzeug) environment
Raspberry + am2302 Measure temperature and humidity with temperature and humidity sensor
Stock investment analysis app made with Raspberry Pi
Logging Inkbird IBS-TH1 mini values with Raspberry Pi
Connect to MySQL with Python on Raspberry Pi
GPS tracking with Raspberry Pi 4B + BU-353S4 (Python)