All the technologies used in this article have the following version numbers: Raspberry Pi 4B; Temperature sensor: DS18B20; Python: 3.7.3; Database: MariadB-10.0.28; Canal (Server/Client) : 1.1.3; Java: 1.8; Javax Mail: 1.5.4 \

Gitee: Temperature Alarm System: Temperature Alarm System based on raspberry PI +DS18B20+Canal (gitee.com)

1. System architecture

Recently, I suddenly came up with a simple idea to implement a temperature alarm system: it is probably to collect indoor temperature through DS18B20, and raspberry PI reads the indoor temperature value circularly. When the temperature alarm threshold is reached, alarm information is written into the database. At the same time, a simple server was set up and a Canal was deployed on it to monitor the data change events of the database in raspberry PI in real time and send emails to remind the temperature warning after obtaining the data.

The whole system can be divided into acquisition layer, communication layer, alarm layer. The system structure is shown in the figure below:

Because the whole process is linear, the whole system is easy to understand.

2. System disassembly

With a system architecture and a simple implementation in mind, let’s think about how to break the system down into small tasks and solve them one by one.

2.1. Data Acquisition Layer

For the data acquisition layer, the difficulty lies in how the raspberry PI reads the temperature information collected by the sensor.

Played microcontroller all know, for analog signal (temperature), we need an AD chip analog signal into 8, 12 or 16 bit digital signal in the form of high and low level sent to the microcontroller for corresponding processing. The temperature sampling accuracy depends on the number of bits in the AD chip. This is a very complicated way to deal with it.

DS18B20 this common temperature sensor directly output digital signal, small volume, strong anti-interference ability. After encapsulation, there are only three pins, which can greatly save IO resources of the processor. When integrated with raspberry PI, the temperature can be written directly to the raspberry PI device file via the driver, saving you the cost of hardware driver development and the hassle of various timing processing logic.

Therefore, the raspberry PI is integrated with the DS18B20, and we can use Python to read device files to get temperature information.

2.2. Communication Layer

For the communication layer of the system, I chose Canal to monitor the MySQL database changes (don’t ask me why I make such trouble (~ ~ ▽ ~) ~, the reason is that I used 🙃 in my work recently).

There are many other options for the communication layer:

  • An easy way to do this is to drop the communication layer and send mail directly in Python
  • The server deploys Netty and implements a simple RPC protocol
  • Alarm information is sent through message queues
  • .

Writing to the database here has the added benefit of being able to extract the data for analysis later when needed. (Ok, this is forcing benefits 🤣)

After the scheme is determined, the implementation is relatively simple. The whole communication layer we need: 1, implement Python write MySQL database; 2. Set up Canal server to monitor database; 3. Post the listening message.

2.3. Alarm Layer

There was no difficulty in sending emails at the alarm layer. At the beginning, I struggled with how to obtain the messages monitored by Canal, whether to use RockeyMQ or Kafka. I was kind of ready to give up on Canal when I thought of it.

When I saw that Canal was implementing a simple canal-client communication of its own, I simply moved the code over and made some simple changes.

Therefore, the technical points of the alarm layer are as follows: 1. Obtain the message delivered by the server through the Canal client; 2. Send an alarm email.

2.4, summary

To sum up, to implement a simple temperature alarm system, complete the following steps:

  1. Use Python to read the raspberry PI device file to obtain the temperature information
  2. Check whether the temperature reaches the threshold and write data to the MySQL database
  3. Set up the Canal server and listen to the MySQL database on the raspberry pie
  4. The canal-client is used to read messages sent by the canal-server and send email alarms

3. Concrete implementation

3.1 Raspberry PI connection DS18B20

DS18B20 used by the system is shown in the following figure:

The temperature measuring module has three pins, which are VCC, GND, and Data Pin (DQ). Because DS18B20 transmits data through only One pin, it uses One Wire communication protocol to transmit data. The pin connections between the module and raspberry PI are shown in the following table:

DS18B20 Raspberry pie note
VCC Pin 1 Physical pins (BOARD code). The DS18B20 used in this system supports 3~5.5V working voltage, so the pin that the raspberry PI can connect can be 3.3V or 5V.
GND Pin 6 Physical pins (BOARD code)
DQ Pin 7 Physical pin (BOARD code); BCM code 4; Function name GPIO.7. The pin is used becauseThe raspberry PI uses Pin 7 as the single-bus communication Pin by default.

Connect DB18B20 pin to raspberry PI using Dupont wire (remember it’s best to connect in case of power failure).

3.2. Enable the raspberry PI single-bus protocol

I usually connect to raspberry PI via SSH, so I can’t directly enable the raspberry PI single line general function through the GUI. You need to enable it by modifying the startup configuration file. (No screen, keyboard configuration, raspberry PI startup connection to wifi, and how to obtain raspberry PI IP address can be referred to here. After obtaining the IP address, remote connection can be achieved through SSH.)

To enable it, proceed as follows:

1. Modify the startup configuration file

vim /boot/config.txt
Copy the code

2. Add the following configuration in the last line of the file. By default, raspberry PI uses Pin 7 (physical Pin, BOARD code; The BCM of this pin is 4) as a single-bus pin, but we can also specify other pins manually.

dtoverlay=w1-gpio
If you want to specify another pin, use the BCM code 18 pin
dtoverlay=w1-gpio,gpiopin=18
Copy the code

The pins of the raspberry PI are: physical pins (BOARD codes); Function name; BCM codes; WiringPi encoding. Here is a pin comparison table, in case you make mistakes.

Ps: It is necessary to connect the right pins, otherwise the corresponding temperature measurement module device file cannot be found in the device file. For example, I can only find the device file with the beginning of 00-** in the device file after the wrong connection at the beginning, so the temperature cannot be read.

3. Restart the raspberry pie

sudo reboot
Copy the code

4. Run the following command to check whether the single-bus protocol is enabled.

lsmod
Copy the code

If the following output is displayed on the terminal, the single-bus protocol is enabled.

5. Enter the following two commands in the terminal. If there is no output, the single-bus has been initialized and temperature collection is ready.

modprobe w1-gpio
modprobe w1-therm
Copy the code

3.3. Obtain the temperature value

1. Enter the system device directory:

cd /sys/bus/w1/devices
Copy the code

2. If all the preceding operations are successful, you can see that there is a folder starting with 28- in the current directory. The name of the folder represents the number of the connected temperature sensor device.

3. Go to the device folder. In the folder, a file named w1_slave stores the sampling temperature of the sensor. Let’s execute the following command to see what is written in the file.

cat w1_slave
Copy the code

The first line is familiar with the words CRC and YSE. You can probably guess that the data generated by using cyclic redundancy check is valid.

The second line, t=27437, shows the current temperature, but divide by 1,000 to convert to degrees Celsius. The figure shows that the current temperature is 27.437℃.

3.4. Python circularly reads the temperature value

This section is relatively easy, just need to use Python built-in OS, time module, here is only the core code, the full code can be accessed at Gitee/GitHub address:

# Sensor Number
deviceNum = "28-01205b67097c"
The address of the file where the device records data
deviceFile ='/sys/bus/w1/devices/' + deviceNum + '/w1_slave'Open and read file data
def readDeviceFile() :
    f = open(deviceFile,'r')
    lines = f.readlines()
    f.close()
    return lines
​
# Parse temperature data
# deviceFile: YES = valid, t = temperature, (t % 1000.0) = degree Celsius
# b7 01 4b 46 7f ff 0c 10 4b : crc=4b YES
# b7 01 4b 46 7f ff 0c 10 4b t=27437
def readTemp() :
    lines = readDeviceFile()
    If the first line does not end with YES, wait 0.2s and repeat until valid data is read
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        # loop to continue reading
        lines = readDeviceFile()
    # Read temperature
    tempIndex = lines[1].find('t=')
    iftempIndex ! = -1:
        temp = lines[1][tempIndex + 2:]
        tempC = float(temp)/1000.0
    return tempC
Copy the code

3.5 raspberry PI install MySQL

Since Raspbian OS is based on Debian, you can download MySQL directly using apt.

sudo apt install mysql-server
Copy the code

After the preceding command is executed, the terminal displays the following information: The raspberry PI operating system does not support MySQL, which is also painful after MySQL was acquired by Oracle. But a prompt tells us that mariadB-Server is available, and that’s where the benefits of open source come in.

Reading package lists... Done Building dependency tree Reading state information... Done Package mysql-server is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, Or is only available from another source However the following packages replace it: MariadB-server-10.0e: Package 'mysql-server' has no installation candidateCopy the code

Next we install mariadB-Server

Sudo apt install mariadb server - 10.0Copy the code

After the initial installation, you can change the password of user root by using the following command:

sudo mysqladmin -u root password "123456"
Copy the code

Then use the login command to log in to Mariabd

sudo mysql -u root -p
Copy the code

Ps: After login, we might try to use Navicat or another client to remotely log in to test, but error code 10061 is displayed

Can't connect to MySQL server on 'address'(10061)
Copy the code

At this point, we can solve the problem as follows:

  • will/etc/mysql/mariadb.conf.d/50-server.cnfThe bind - address = 127.0.0.1Modified to0.0.0.0. Or just comment it outThe bind - address = 127.0.0.1
  • Restart the MySQL,service mysqld restart

3.6. Write to MySQL in Python

Python3 MySQL database connection – PyMySQL driver to get started quickly.

There is something to note here: PyMySQL is a Python3 library installed using PIp3. The raspberry PI system I originally burned only carried Python2 by default. Therefore, you can uninstall Python2 from the original system and install Python3 by upgrading the raspberry PI built-in Python2.7 to Python3

MySQL CRUD: MySQL CRUD: MySQL CRUD: MySQL CRUD: MySQL CRUD: MySQL CRUD

def testInsertFunction(cursor) :
    try :
        sql = """INSERT INTO warn(warning_flag, insert_time) values (%s, %s)"""
        data_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # System time
        result = cursor.execute(sql, (1, data_time)) # add parameters
        print(result)
    except Exception as e:
        print("Insert data failed :", e)
    else:
        print("Insert data successfully :")
        
def writeDatebase() :
    conn = pymysql.connect(
        host = "ipaddress", 
        port = 3306, 
        user = "root", 
        passwd = "password", 
        db = "project1", 
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor()
    testInsertFunction(cursor)
    cursor.close()
    conn.close()
Copy the code

3.7. Set up canal-server

Here, I did not choose to build canal-Server in raspberry PI, but set up another VIRTUAL machine.

For the Canal version, I chose 1.1.3. You also need to pay attention to the version selection, the client and the server version had better be consistent; Canal is the best choice for MySQL with a higher version. Otherwise, there will be various problems, for example, I have a low version of Canal connection to the high version of MySQL password encryption problem.

The method of setting up canal-server is as follows:

  • Download the Canal – Server
Wget HTTP: / / https://github.com/alibaba/canal/releases/download/canal-1.1.3/canal.deployer-1.1.3.tar.gzCopy the code
  • unzip
Mkdir/TMP /canal tar ZXVF ccanals. Deployer-1.1.3.tar. gz -c/TMP /canalCopy the code
  • After the decompression is complete, go to the directoryBin, conf, lib, logsFour folders
cd /tmp/canal
ls
Copy the code
  • The four directories are used as follows:

    • Bin: stores the executable file used to start and stop the canal-server
    • Conf: Stores the configuration file of the Canal-server
    • Lib: stores the runtime dependent JAR package
    • Logs: Stores log files
  • Modifying a Configuration File

vim conf/example/instance.properties
Copy the code
  • Below I only list the configurations I have modified. For others, you can refer to the official website for configuration details
# slaveId is not the same as masterId
canal.instance.mysql.slaveId=1234
The following is the MySQL configuration
canal.instance.master.address=address:3306
canal.instance.dbUsername=root
canal.instance.dbPassword=password
Copy the code
  • Start the
sh bin/startup.sh
Copy the code
  • Viewing Server Logs
tail -f logs/canal/canal.log
Copy the code
  • Viewing Instance Logs
tail -f logs/example/example.log
Copy the code
  • Shut down
sh bin/stop.sh
Copy the code

3.8. Use canal-client and send the email

In this part, I used the Example test case on Canal’s official website and made some modifications on it.

First, the following dependencies were introduced in the project:

<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.1.3</version>
</dependency><dependency>
    <groupId>com.sun.mail </groupId>
    <artifactId>javax.mail </artifactId>
    <version>1.5.4 </version>
</dependency>
Copy the code

Then copy SimpleCanalClientTest, AbstractCanalClientTest, BaseCanalClientTest in Canal-example into the project, and write a tool class to send mail to complete the monitoring and sending mail. See Gitee or GitHub for detailed code.

4. Achievement Display

It can be seen from the following results: at the beginning, the sensor has been polling the temperature value, and when the temperature exceeds 32.5℃, the output has been sent immediately. At this point, IDEA (the console with IDEA in black at the bottom) also outputs corresponding logs. After 1 to 2 seconds, the mail also arrives in the mailbox.