[100 million controllable] first day system analysis and design

Posted by litarena on Sat, 22 Jan 2022 21:53:09 +0100

Chapter 1 Analysis and design of controllable system

Learning objectives

  • Understand the application field and development status of the Internet of things
  • Be able to describe controllable core functions
  • Be able to draw a controllable system architecture
  • Be able to complete the preparation of the controllable environment and understand the controllable functional structure
  • Complete the development of equipment management related functions

1. Internet of things industry analysis

1.1 what is the Internet of things

Internet of Things (English: Internet of Things, abbreviation: IoT) originated in the field of media and is the third revolution of information technology industry. Internet of Things refers to connecting any object with the network through information sensing equipment and according to the agreed protocol. Objects exchange and communicate information through information media, so as to realize the functions of intelligent identification, positioning, tracking, supervision and so on.

There are three key technologies in the application of Internet of things, namely perception layer, network transmission layer and application layer.

Definition of Chinese Internet of things:

The most concise and clear definition: Internet of things is a network based on information carriers such as the Internet and traditional telecommunication networks, which enables all ordinary physical objects that can be independently addressed to realize interconnection. It has three important characteristics: common object equipment, autonomous terminal interconnection and pervasive service intelligence.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-A2nJMnqj-1642866059813)(images/1-1.png)]

Four concepts appear in the figure above. Let's explain them here:

The integration of informatization and industrialization is a high-level and deep combination of informatization and industrialization, which refers to driving industrialization with informatization, promoting informatization with industrialization, and taking a new road of industrialization; The core of the integration of the two modernizations is information support and the pursuit of sustainable development model.

The full name of M2M is Machine to Machine, which refers to the transmission of data from one terminal to another, that is, the dialogue between machines.

Radio Frequency Identification (RFID) is the abbreviation of Radio Frequency Identification. Its principle is non-contact data communication between reader and tag to achieve the purpose of identifying targets. RFID is widely used. Typical applications include animal chip, automobile chip anti-theft device, access control, parking lot control, production line automation and material management.

Sensor network is the abbreviation of sensor network computer,signal communication , networks, intelligent computing, sensors Embedded system It is a new interdisciplinary and integrated discipline in many fields, such as, microelectronics, etc. it forms an autonomous network with a large number of various sensor nodes (integrating sensing, acquisition, processing and transceiver), so as to realize the dynamic intelligent collaborative perception of the physical world.

As can be seen from the above figure, the Internet of things covers the four areas mentioned above.

"One sentence" understanding the Internet of things

All objects are connected to the Internet through information sensing equipment for information exchange, that is, objects interact with each other, so as to realize intelligent identification and management.

Historical Tracing

When China put forward the concept of the Internet of things in 1999, it was called sensor network. The Chinese Academy of Sciences started the research and development of sensor networks as early as 1999. Compared with other countries, China's technology R & D level is in the forefront of the world, with simultaneous advantages and significant influence.
On November 27, 2005, at the information society summit held in Tunis, the International Telecommunication Union (ITU) released ITU Internet Report 2005: Internet of things, which formally put forward the concept of Internet of things.
On August 24, 2009, Wang Jianzhou, President of China Mobile, also mentioned the concept of the Internet of things in a public speech in Taiwan.
Zhu Hongren, chief engineer of the Ministry of industry and information technology, said at the 2009 summer report meeting on China's industrial operation that the Internet of things is a new concept. As of 2009, there is no conventional and recognized concept. He said that in general, the "Internet of things" refers to a new technology that connects various sensors with the existing "Internet".
The Internet of Things is based on the computer Internet, using RFID, wireless data communication and other technologies to construct an "Internet of Things" covering everything in the world. In this network, goods can "communicate" with each other without human intervention. Its essence is to use radio frequency automatic identification (RFID) technology to realize the automatic identification of goods (commodities) and the interconnection and sharing of information through computer Internet.
The advent of the concept of the Internet of things has broken the previous traditional thinking. In the past, the idea has been to separate physical infrastructure from IT infrastructure, including airports, roads and buildings on the one hand, and data centers, personal computers and broadband on the other. In the era of Internet of things, reinforced concrete and cables will be integrated with chips and broadband into a unified infrastructure. In this sense, infrastructure is more like a new earth. Therefore, some people in the industry believe that the Internet of things and smart grid are an organic part of the smart earth.

1.2 Internet of things applications

1. Smart home
Smart home uses advanced computer technology, intelligent hardware (helium krypton wifi, Zigbee, Bluetooth, Nb IOT, etc.), Internet of things technology and communication technology to organically combine with various subsystems of furniture life, so as to make home life more comfortable, convenient, effective and safe through overall management. Smart home mainly includes smart speaker, smart lamp, smart socket, smart lock, smart thermostat, floor sweeping robot, etc.

2. Intelligent transportation
Intelligent transportation is a comprehensive transportation system that effectively integrates intelligent sensing technology, information network technology, communication transmission technology and data processing technology represented by Internet of things, Internet and cloud computing, and applies them to the whole transportation system to play a role in a larger space-time range [2]. Smart transportation is a new large-scale transportation development model with smart road network, smart travel, smart equipment, smart logistics and smart management as important contents and highly integrated information technology and comprehensive utilization of information resources as main features. Relying on Dimon technology's rich development experience and strong technical accumulation in the fields of cloud computing, Internet of things, big data, financial technology and so on, it took three years to build China's first high-end intelligent transportation overall solution integrating innovative business models in the fields of online car hailing, intelligent parking, car rental, automobile finance and other intelligent travel [3].

4. Smart grid
Smart grid is a comprehensive digital and physical composite system integrating sensing, communication, calculation, decision-making and control based on the traditional power grid. By obtaining the operation status of node resources and equipment at all levels of the power grid, it carries out hierarchical control management and power allocation, realizes the high integration of energy flow, information flow and business flow, and improves the operation stability of the power system, In order to maximize the efficiency and utilization of equipment, improve safety and reliability, save energy and reduce emission, improve the power supply quality of users and improve the utilization efficiency of renewable energy.

4. Smart city
Smart city is to use information and communication technology means to sense, analyze and integrate various key information of urban operation core system, so as to make intelligent response to various needs including people's livelihood, environmental protection, public safety, urban services and industrial and commercial activities. Its essence is to use advanced information technology to realize urban intelligent management and operation, so as to create a better life for people in the city and promote the harmonious and sustainable growth of the city.
With the continuous development of human society, cities will carry more and more people in the future. At present, China is in a period of accelerated urbanization, and the problem of "urban disease" in some areas is becoming more and more serious. In order to solve the problems of urban development and realize urban sustainable development, building a smart city has become an irreversible historical trend of urban development in the world.
The construction of smart city has been carried out in many areas at home and abroad, and a series of achievements have been made, such as smart Shanghai and smart Shuangliu; Abroad, such as Singapore's "smart country plan" and South Korea's "U-City plan".

5. Other fields: intelligent automobile, intelligent building, intelligent water, intelligent commerce, intelligent industry, safe city, intelligent agriculture, intelligent security, intelligent medical treatment, etc.

1.3 development status of Internet of things

Consumer IOT is booming and still in its infancy

The Internet of things connects things and people through relevant equipment.

(1) Scale: the scale of the global Internet of things industry increased from US $50 billion in 2008 to only US $151 billion in 2018, with an average annual compound growth rate of 11.7%. The scale of China's Internet of things industry reached 1150 billion yuan in 2017, which has further accelerated since 2011. The average annual compound growth rate from 2009 to 2017 reached 26.9%. The development speed of China's Internet of things is faster than the global average.

(2) Penetration: the penetration of the global Internet of things industry reached 12% in 2013 and 29% in 2017, more than doubling. It is expected that more than 65% of enterprises and organizations will apply Internet of things products and solutions in 2020. In recent years, the scale of China's Internet of things market has been expanding, from 365 billion yuan in 2012 to 1165.5 billion yuan in 2017, with a compound annual growth rate of 25%.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-sCzdXSNO-1642866059815)(images/1-2.png)]

Market scale of China's Internet of things from 2012 to 2017 (100 million yuan)

[external chain image transfer fails, and the source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-9VlvXO8N-1642866059815)(images/1-3.png)]

Global Internet of things penetration change

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ms4CrORe-1642866059816)(images/1-4.png)]

Consumer Internet of things: still in its infancy

Consumer IOT is expected to grow rapidly.

(1) Global: in 2017, the global sales of consumer IOT hardware reached US $485.9 billion, a year-on-year increase of 29.5%, and the compound growth rate from 2015 to 2017 reached 26.0%. The sales volume is expected to reach US $1550.2 billion in 2022, with an average annual compound growth rate of 26.1% from 2017 to 2022. The scale of global consumer IOT market shows a trend of further acceleration.

(2) Chinese mainland: 2017 Chinese mainland consumptive IOT hardware sales amount to 118 billion 800 million US dollars, up 30% compared to the same period, 2015-2017 compound speed up to 28.9%. The sales volume is expected to reach USD 311.8 billion in 2022, with an average annual compound growth rate of 21.3% from 2017 to 2022. Before 2017, due to the rapid development of Xiaomi and other companies, the overall development of China's consumer IOT was faster than the global average. After 2017, with the rapid development of China's consumer IOT, the global consumer IOT will develop faster. (3) Connected equipment: the number of global consumer IOT terminals reached 4.9 billion in 2017, with an average annual compound growth rate of 27.7% in 2015-2017, 15.3 billion in 2022 and 25.4% in 2017-2022. In 2017, the number of China's consumer IOT terminals accounted for 26.5% of the world's total, which is expected to increase to 29.4% in 2022, and the compound growth rate from 2017 to 2022 is expected to reach 28.2%.

Global consumer IOT market size:
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-H5PXUdfG-1642866059816)(images/1-5.png)]
China's consumer IOT market size:
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-duugybgQ-1642866059817)(images/1-6.png)]
Number of IOT terminals worldwide and in China:
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-E9nlj8wt-1642866059818)(images/1-7.png)]

200 million controllable demand analysis

2.1 requirements overview

As a middle office, yicontrollable carries out real-time online monitoring and early warning of equipment operation without business-related functions.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-yCEajXFo-1642866059818)(images/1-14.png)]

List of core functions:

(1) message data collection and index analysis: the data source of the whole system is the message sent by the receiving equipment. The index data of the subject and message content fields are defined as filter conditions in the system, so as to collect and analyze the message.

(2) alarm monitoring: by comparing with various alarm level data defined in the system, once a message triggering the alarm level is found, the alarm information will be transmitted to other systems through the webhook associated with the alarm

(3) GPS positioning monitoring: collect the GPS positioning of each equipment and provide the function of equipment position query.

(4) data Kanban: provide rich user-defined data kanban.

2.2 business structure diagram

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-BWQyGJ4L-1642866059819)(images/1-19.png)]

From the above figure, we can see that the real system is divided into six functional modules: graphic monitoring module, data detail display module, Kanban management module, equipment management module, alarm management module and system management module.

2.3 core business description

Product prototype address:

https://app.mockplus.cn/run/prototype/yYVLQlJ-YN6/JhE4uVilt/4nw_LQ8n7

300 million controllable system architecture

3.1 system architecture diagram

The technical architecture of the whole system is as follows:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-uvyszivM-1642866059820)(images/1-10.png)]

The prefabricated data will be stored in mysql, the indicator data reported by the equipment, including alarm data, will be stored in influxDB, and the geographic location information data of the equipment will be stored in ES for later search. In order to improve the operation stability of the system, some frequently accessed data are stored in redis, because considering that the data reported by the equipment is very frequent, if only relying on MySQL database, it will easily increase the CPU occupation rate of MySQL server to 100%, which will lead to the collapse of the whole system.

Some basic configurations are put into the consumer configuration center. Considering the horizontal expansion ability of the system, the whole system is built into a micro service based on the consul registry.

3.2 database design

mysql database has five tables:

Administrator table tb_admin

Listingdata typeexplain
idintTable primary key id, self incrementing
login_namevarchar(50)Login account
passwordvarchar(60)password
typetinyintType 1: Super administrator 2: ordinary users are currently reserved fields
boardvarchar(50)Kanban list

Indicator configuration table tb_quota

Listingdata typeexplain
idintTable primary key id
namevarchar(50)Indicator name
unitvarchar(20)Index unit
subjectvarchar(50)Message subject
value_keyvarchar(50)Indicator value field
sn_keyvarchar(50)Device ID field
webhookvarchar(1000)web hook
value_typevarchar(10)Indicator field type, Double, integer, Boolean
reference_valuevarchar(100)reference value

Alarm configuration table tb_alarm

Listingdata typeexplain
idintTable primary key id, self incrementing
namevarchar(50)Alarm indicator name
quota_idintAssociated indicator name
operatorvarchar(10)operator
thresholdintAlarm threshold
levelintAlarm level 1: general 2: severe
cycleintSilence period (in minutes)
webhookvarchar(1000)web hook address

Panel configuration table tb_board

Listingdata typeexplain
idintTable primary key id, self incrementing
admin_idintAdministrator id
namevarchar(50)Kanban name
quotavarchar(100)index
devicevarchar(100)equipment
systemtinyintIs it a system Kanban
disabletinyintDo not display

GPS configuration table tb_gps

Listingdata typeexplain
idbigintTable primary key id
subjectvarchar(50)Message subject
sn_keyvarchar(50)Device ID field
typetinyintType (single field, double field)
value_keyvarchar(50)Latitude and longitude field
separationvarchar(10)Longitude and latitude separator
longitudevarchar(20)Longitude field
latitudevarchar(20)Dimension field

4. Basic code analysis

4.1 environmental preparation

4.1.1 loading virtual machine image

Use the virtual machine image provided with the course.

NAT mode is recommended for network connection.

The code 192.168.200.128 provided in this course handout is the host IP. If it is not the IP after you load the image, please adjust it yourself.

The docker environment has been installed and the required images have been pulled out of the box.

4.1.2 MySQL database and table creation

mysql connecting to the virtual machine, user name root, password root123

Create database ykk, create table

create table if not exists tb_admin
(
	id int auto_increment
		primary key,
	login_name varchar(50) null comment 'Login name',
	password varchar(60) null comment 'password',
	type tinyint null comment 'Type 1 super administrator 0 ordinary user',
	board varchar(50) null comment 'bulletin board'
);

create table if not exists tb_alarm
(
	id int auto_increment comment 'id'
		primary key,
	name varchar(50) null comment 'Alarm name',
	quota_id int null comment 'index id',
	operator varchar(10) null comment 'operator',
	threshold int null comment 'Alarm threshold',
	level int null comment 'Alarm level 1 general 2 severe',
	cycle int null comment 'Silence period (minutes)',
	webhook varchar(1000) null comment 'web hook',
	constraint tb_alarm_name_uindex
		unique (name)
);

create table if not exists tb_board
(
	id int auto_increment comment 'id'
		primary key,
	admin_id int default 1 null comment 'administrators id',
	name varchar(50) null comment 'Kanban name',
	quota varchar(100) default '0' null comment 'index(Set on trend)',
	device varchar(100) null comment 'equipment(Cumulative)',
	`system` tinyint default 0 null comment 'Is it a system Kanban',
	disable tinyint default 0 null comment 'Do not display',
	constraint tb_board_name_uindex
		unique (name)
);


create table if not exists tb_gps
(
	id int not null comment 'id'
		primary key,
	subject varchar(50) null comment 'theme',
	sn_key varchar(50) null comment 'Device ID field',
	single_field tinyint null comment 'Type (single field, double field)',
	value_key varchar(50) null comment 'Latitude and longitude field',
	separation varchar(10) null comment 'Longitude and latitude separator',
	longitude varchar(20) null comment 'Longitude field',
	latitude varchar(20) null comment 'Dimension field',
	constraint tb_gps_subject_uindex
		unique (subject)
);

create table if not exists tb_quota
(
	id int auto_increment comment 'id'
		primary key,
	name varchar(50) null comment 'Indicator name',
	unit varchar(20) null comment 'Index unit',
	subject varchar(50) null comment 'Message subject',
	value_key varchar(50) null comment 'Indicator value field',
	sn_key varchar(50) null comment 'Device ID field',
	webhook varchar(1000) null comment 'web hook',
	value_type varchar(10) null comment 'Indicator field type, Double,Inteter,Boolean',
	reference_value varchar(100) null comment 'reference value',
	constraint tb_quota_name_uindex
		unique (name)
);

4.1.3 Consul add configuration

(1) Enter Consul

Open the browser and enter the address http://192.168.200.128:8500/

(2) Create the configuration key as config / backend service / data value as follows

spring: 
  datasource:
    url: jdbc:mysql://192.168.200.128:3306/ykk?useUnicode=true&autoReconnect=true&autoReconnectForPools=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: root123
    driver-class-name: com.mysql.jdbc.Driver
  redis:
    host: 192.168.200.128
    port: 6379
    database: 0
    lettuce:
      pool:
        max-active: 10
        max-wait: -1
        max-idle: 5
        min-idle: 1
      shutdown-timeout: 100
    timeout: 1000
    password:  

4.2 engineering structure analysis

The screenshot of the main framework of the project is as follows:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-cF1oOs9k-1642866059821)(images/1-12.png)]

At present, the project is mainly divided into two parts: YKK common and YKK backend.

YKK common module stores some basic general definitions of the system, including general exception definitions, database connection definitions, and some constant definitions.

YKK backend module is the implementation code of our background logic, which is divided into specific packages according to specific function implementation.

4.3 core code analysis

4.3.1 user login and JWT verification

(1) User login business logic

package com.yikekong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.yikekong.entity.AdminEntity;
import com.yikekong.mapper.AdminMapper;
import com.yikekong.service.AdminService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper,AdminEntity> implements AdminService{
    @Override
    public Integer login(String loginName, String password) {
        if(Strings.isNullOrEmpty(loginName) || Strings.isNullOrEmpty(password)){
            return -1;
        }
        QueryWrapper<AdminEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(AdminEntity::getLoginName,loginName);
        AdminEntity adminEntity = this.getOne(queryWrapper);
        if(adminEntity == null)
            return -1;

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if(passwordEncoder.matches(password,adminEntity.getPassword())){
            return adminEntity.getId();
        }

        return -1;
    }
}

(2) User login controller class

@RestController
public class AdminController{
    @Autowired
    private AdminService adminService;

    @PostMapping("/login")
    public LoginResultVO login(@RequestBody AdminVO admin){
        LoginResultVO result = new LoginResultVO();
        Integer adminId = adminService.login(admin.getLoginName(),admin.getPassword());
        if(adminId < 0){
            result.setLoginSuccess(false);
            return result;
        }
        result.setAdminId(adminId);
        String token = JwtUtil.createJWT(adminId);
        result.setToken(token);
        result.setLoginSuccess(true);

        return result;
    }
}

(3) Login verification

AuthFilter in httpfilter package is our jwt filter, which is mainly used to verify jwt token. The implementation of this class is as follows:

package com.yikekong.httpfilter;


import org.elasticsearch.common.Strings;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@WebFilter(urlPatterns = "/*",filterName = "authFilter")
public class AuthFilter implements Filter{
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)servletRequest;
        HttpServletResponse resp = (HttpServletResponse)servletResponse;
        String path = ((HttpServletRequest) servletRequest).getServletPath();
        //If the login interface is accessed, jwt token verification is not performed
        if(path.equals("/login")){
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        String authToken = ((HttpServletRequest) servletRequest).getHeader("Authorization");
        //How to directly return verification failure if the Authorization value does not exist in the header
        if(Strings.isNullOrEmpty(authToken)){
            ((HttpServletResponse) servletResponse).setStatus(HttpStatus.UNAUTHORIZED.value());
            return;
        }

        try {
            JwtUtil.parseJWT(authToken);
        } catch (Exception e) {
            //jwt verification failed, return
            ((HttpServletResponse) servletResponse).setStatus(HttpStatus.UNAUTHORIZED.value());
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }
}

4.3.2 indicator management - create indicators

The Create method of the QuotaController is used to create indicators

/**
 * Create indicators
 * @param vo
 * @return
 */
@PostMapping
public boolean create(@RequestBody QuotaVO vo){
    QuotaEntity quotaEntity = new QuotaEntity();
    BeanUtils.copyProperties(vo,quotaEntity);
    return quotaService.save(quotaEntity);
}

The vo class received by this method is the encapsulated view object of the front end. In many cases, the data transmitted from the front end may not be completely consistent with the corresponding data from our back-end database, so our usual practice is to create a separate vo class for data transmission with the front end. In this way, if the sending structure of the data object passed by the front end changes, it will not affect the back-end database structure.

BeanUtils.copyProperties(vo,quotaEntity); It is used for copying object data. If two objects have the same properties, the properties will be copied automatically, so as to avoid a large number of setter methods in the code.

5. Equipment management

5.1 equipment addition

5.1.1 demand analysis

In a controllable system, we cannot and do not need to add devices from the system interface. The addition of equipment is saved after the message sent by the equipment is received and parsed. Because the number of devices used in Internet of things applications may be very large, and the reading and writing frequency of this part of data is very frequent, we use elasticsearch as the database of devices.

5.1.2 index library structure design

device library

Listingdata typeexplain
deviceIdkeywordEquipment number
alarmbooleanAlarm or not
alarmNamekeywordAlarm name
levelintegerAlarm level
onlinebooleanOnline
statusbooleanswitch
tagkeywordlabel

5.1.3 code implementation

(1) Create index library (open kibana) http://192.168.200.128:5601/)

PUT /devices
{
    "mappings": {
        "properties": {
            "deviceId": {
                "type": "keyword"
            },
            "alarm": {
                "type": "boolean"
            },
            "alarmName": {
                "type": "keyword"
            },
            "level": {
                "type": "integer"
            },
            "online": {
                "type": "boolean"
            },
            "status": {
                "type": "boolean"
            },
            "tag": {
                "type": "keyword"
            }
        }
    }
}

(2)pom.xml add configuration

<!--es Correlation dependency-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.7.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.7.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.7.1</version>
</dependency>
<!--es Dependent end-->

(3) Add the configuration in the configuration file and add the following configuration to the spring node

  elasticsearch:
    rest:
      uris: http://192.168.200.128:9200

(4) Create package com yikekong. DTO, create a DTO class that encapsulates the device

package com.yikekong.dto;

import lombok.Data;

import java.io.Serializable;

/**
 * Device DTO
 */
@Data
public class DeviceDTO implements Serializable {

    private String deviceId;//Equipment number

    private Boolean alarm;// Alarm or not

    private String alarmName;//Alarm name 

    private Integer level;//Alarm level

    private Boolean online;//Online

    private String tag;// label

    private Boolean status;//Switch status
        
}

(5) Create com yikekong. Es package, create an ESRepository class under the package, and write methods to add devices

package com.yikekong.es;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.yikekong.dto.DeviceDTO;
import com.yikekong.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class ESRepository{

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * Add device
     * @param deviceDTO
     */
    public  void addDevices(DeviceDTO deviceDTO){
        if(deviceDTO==null ) return;
        if(deviceDTO.getDeviceId()==null) return;
        IndexRequest request=new IndexRequest("devices");
        try {
            String json = JsonUtil.serialize(deviceDTO);
            Map map = JsonUtil.getByJson(json, Map.class);
            request.source(map);
            request.id(deviceDTO.getDeviceId());
            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("Exception in adding device");
        }
    }
}

5.1.4 unit test

Write unit tests

import com.yikekong.YkkApplication;
import com.yikekong.dto.DeviceDTO;
import com.yikekong.es.ESRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = YkkApplication.class)
@RunWith(SpringRunner.class)
public class EsTest {

    @Autowired
    private ESRepository esRepository;

    @Test
    public void testAdd(){
        DeviceDTO deviceDTO=new DeviceDTO();
        deviceDTO.setDeviceId("123456");
        deviceDTO.setStatus(true);
        deviceDTO.setAlarm(false);
        deviceDTO.setLevel(0);
        deviceDTO.setAlarmName("");
        deviceDTO.setOnline(true);
        deviceDTO.setTag("");
        esRepository.addDevices(deviceDTO);
    }
}

Query the data and verify the running results

GET devices/_search
{
  "query": {
    "match_all": {}
  }
}

5.2 query equipment according to equipment ID

5.2.1 demand analysis

Query the device information from elasticsearch according to the id. This method needs to be called in the logic of message parsing to realize the query of equipment.

5.2.2 code implementation

ESRepository class add method

/**
 * Query equipment according to equipment id
 * @param deviceId  Device id
 * @return
 */
public DeviceDTO searchDeviceById(String deviceId){
    SearchRequest searchRequest=new SearchRequest("devices");
    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.termQuery("_id",deviceId));
    searchRequest.source(searchSourceBuilder);
    try {
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();
        long hitsCount = hits.getTotalHits().value;
        if(hitsCount<=0) return null;
        DeviceDTO deviceDTO=null;
        for(SearchHit hit:hits){
            String hitResult = hit.getSourceAsString();
            deviceDTO=JsonUtil.getByJson(hitResult,DeviceDTO.class  );
            deviceDTO.setDeviceId(deviceId);
            break;
        }
        return deviceDTO;

    } catch (IOException e) {
        e.printStackTrace();
        log.error("Query device exception");
        return null;
    }
}

5.2.3 unit test

Write unit test methods to verify whether the code is correct

@Test
public void testSearchById(){

    DeviceDTO deviceDTO = esRepository.searchDeviceById("123456");
    try {
        String json = JsonUtil.serialize(deviceDTO);
        System.out.println(json);

    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }

}

5.3 setting equipment status

5.3.1 demand analysis

When we do not need to receive messages from a device, we can turn it off. The closed equipment does not process the received message indicators.

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-UI5uF1Uo-1642866059821)(images/1-15.png)]

5.3.2 API interface

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-vHK6Fx4g-1642866059822)(images/1-16.png)]

5.3.3 code implementation

(1) The ESRepository class adds methods to enable and disable devices.

/**
 * Update device status
 * @param deviceId
 * @param status
 * @return
 */
public boolean updateStatus(String deviceId,Boolean status){
    UpdateRequest updateRequest=new UpdateRequest("devices",deviceId)
            .doc( "status",status );
    try {
        restHighLevelClient.update( updateRequest,RequestOptions.DEFAULT );
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("Error updating device status");
        return false;
    }
}

(2) New method definition for DeviceService

/**
 * Change device status
 * @param deviceId
 * @param status
 * @return
 */
boolean setStatus(String deviceId, Boolean status);

DeviceServiceImpl implementation method

@Autowired
private ESRepository esRepository;

@Override
public boolean setStatus(String deviceId, Boolean status) {
    DeviceDTO deviceDTO = findDevice(deviceId);
    if( deviceDTO==null ) return false;
    return esRepository.updateStatus(deviceId,status);
}

/**
 * Query equipment according to equipment id
 * @param deviceId
 * @return
 */
private DeviceDTO findDevice(String deviceId){
    DeviceDTO deviceDTO = esRepository.searchDeviceById(deviceId);
    return deviceDTO;
}

(3) New method of DeviceController

/**
 * Interface for setting status
 * @param deviceVO
 * @return
 */
@PutMapping("/status")
public boolean setStatus(@RequestBody DeviceVO deviceVO){
    return deviceService.setStatus(deviceVO.getSn(),deviceVO.getStatus());
}

5.3.4 interface test

(1) Run YkkApplication startup project

(2) Test interface. In order to facilitate the test, we use the Rest Client plug-in of vscode to test. The script is "materials \ test \ yikekong.http" provided by the course. Open it with vscode and find the following script

####Modify device status########
PUT   http://{{hostname}}:{{port}}/device/status HTTP/1.1
Authorization: {{Authorization}}
Content-Type: {{contentType}}

{
    "sn":"123456",
    "status":true
}

We can modify the status value and click the Send Request link to test

5.4 setting equipment labels

5.4.1 demand analysis

We can set one or more labels for each device for the convenience of querying the device later. There is no function to update the device label on the front-end interface. This function only provides a calling interface for external systems.

5.4.2 code implementation

(1) ESRepository class add method

/**
 * Update device label
 * @param deviceId
 * @param tags
 * @return
 */
public boolean updateDeviceTag(String deviceId,String tags){
    UpdateRequest updateRequest=new UpdateRequest("devices",deviceId)
            .doc( "tag",tags );
    try {
        restHighLevelClient.update( updateRequest,RequestOptions.DEFAULT );
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("Error updating device label");
        return false;
    }
}

(2) DeviceService new method

/**
 * Update device label
 * @param deviceId
 * @param tags
 * @return
 */
boolean updateTags(String deviceId,String tags);

DeviceServiceImpl implementation method

@Override
public boolean updateTags(String deviceId, String tags) {
    DeviceDTO deviceStatus = findDevice(deviceId);
    if(deviceStatus == null) return false;
    esRepository.updateDeviceTag(deviceId,tags);
    return true;
}

(3) New method of DeviceController

/**
 * Interface for setting labels
 * @param deviceVO
 * @return
 */
@PutMapping("/tags")
public boolean setTags(@RequestBody DeviceVO deviceVO){
    return deviceService.updateTags(deviceVO.getSn(),deviceVO.getTags());
}

(4) The doFilter code of AuthFilter class is added to release tags

//The tag interface does not verify the token
if(path.contains("/device/tags")){
	filterChain.doFilter(servletRequest, servletResponse);
	return;
}

5.4.3 interface test

(1) Start project

(2) Find the following script and test it

####Set device label############
PUT   http://{{hostname}}:{{port}}/device/tags HTTP/1.1
Content-Type: {{contentType}}

{
    "sn":"123456",
    "tags":"school"
}

5.5 update equipment alarm information

5.5.1 demand analysis

When the indicator information in the message sent by the equipment reaches the alarm level, we should update the equipment alarm information (whether alarm, alarm level and alarm name) in elasticsearch

5.5.2 code implementation

ESRepository class add method

/**
 * Update equipment alarm information
 * @param deviceDTO
 * @return
 */
public boolean updateDevicesAlarm(DeviceDTO deviceDTO){
    UpdateRequest updateRequest=new UpdateRequest("devices",deviceDTO.getDeviceId())
            .doc(   "alarm",deviceDTO.getAlarm(),//Alarm or not
                    "level",deviceDTO.getLevel(),//Alarm level
                    "alarmName",deviceDTO.getAlarmName() );//Alarm name 
    try {
        restHighLevelClient.update( updateRequest,RequestOptions.DEFAULT );
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("Error updating equipment alarm information");
        return false;
    }
}

5.5.3 unit test

Write unit tests and add test methods in TestES

@Test
public void testAlarm(){
    DeviceDTO deviceDTO=new DeviceDTO();
    deviceDTO.setDeviceId("123456");
    deviceDTO.setAlarm(true);
    deviceDTO.setLevel(1);
    deviceDTO.setAlarmName("The temperature is too high");

    esRepository.updateDevicesAlarm(deviceDTO);

}

5.6 update online status

5.6.1 demand analysis

Online status refers to whether the device is online. If there is a network failure, the device will be offline. The 100 million controllable system can monitor the online and offline status of the equipment

5.6.2 code implementation

Here we need to add methods in the ESRepository class to update the online status.

/**
 * Update online status
 * @param deviceId
 * @param online
 * @return
 */
public boolean updateOnline(String deviceId,Boolean online){
    UpdateRequest updateRequest=new UpdateRequest("devices",deviceId)
            .doc( "online",online );
    try {
        restHighLevelClient.update( updateRequest,RequestOptions.DEFAULT );
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("Error updating online status");
        return false;
    }
}

5.6.3 unit test

Write unit tests and add test methods in TestES

@Test
public void testOnline(){
    esRepository.updateOnline("123456",false);
}

5.7 paging query equipment

5.7.1 demand analysis

There are two pages that need to implement paging query devices

(1) Equipment management, as shown in the figure below, requires equipment number and label as query criteria for paging query

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-x7TlcUK9-1642866059823)(images/1-13.png)]

(2) The equipment details are shown in the following figure. The equipment status, label and equipment number are required as query criteria for paging query

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-h3ZBbmT5-1642866059824)(images/1-18.png)]

The equipment details page has an additional query condition of "equipment status" than the equipment management. The equipment status has four values: Online (0), offline (1), general alarm (2) and serious alarm (3).

In order to avoid code redundancy, we can implement these two functions in the same way.

5.7.2 code implementation

ESRepository class add method

/**
 * Paging query device
 * @param page Page number
 * @param pageSize Page size
 * @param deviceId Equipment number
 * @param tags label
 * @param state state
 * @return
 */
public Pager<DeviceDTO> searchDevice(Long page,Long pageSize,String deviceId,String tags,Integer state){

    SearchRequest searchRequest=new SearchRequest("devices");
    SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();
    //Condition query
    BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
    //Equipment number
    if(!Strings.isNullOrEmpty(deviceId)) {
        boolQueryBuilder.must(QueryBuilders.wildcardQuery("deviceId", deviceId + "*"));
    }
    //label
    if(!Strings.isNullOrEmpty(tags) ){
        boolQueryBuilder.must(QueryBuilders.wildcardQuery("tag","*"+tags+"*"));
    }
    //Status (online status and alarm status) 0: online 1: offline 2: general alarm 3: serious alarm
    if(state!=null){
        if(state.intValue()==0){
            boolQueryBuilder.must( QueryBuilders.termQuery("online",true));
        }
        if(state.intValue()==1){
            boolQueryBuilder.must( QueryBuilders.termQuery("online",false));
        }
        if(state.intValue()==2){
            boolQueryBuilder.must( QueryBuilders.termQuery("level",1));
        }
        if(state.intValue()==3){
            boolQueryBuilder.must( QueryBuilders.termQuery("level",2));
        }
    }
    sourceBuilder.query(boolQueryBuilder);
    //paging
    sourceBuilder.from( (page.intValue()-1)*pageSize.intValue()  );
    sourceBuilder.size( pageSize.intValue() );
    sourceBuilder.trackTotalHits(true);

    //sort
    sourceBuilder.sort("level", SortOrder.DESC);//Front row with high alarm level
    searchRequest.source(sourceBuilder);
    try {
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        List<DeviceDTO> devices= Lists.newArrayList();
        for(SearchHit hit: searchHits){
            String hitResult = hit.getSourceAsString();
            DeviceDTO deviceDTO = JsonUtil.getByJson(hitResult, DeviceDTO.class);
            devices.add(deviceDTO);
        }
        Pager<DeviceDTO> pager=new Pager<>(   searchResponse.getHits().getTotalHits().value,pageSize );
        pager.setItems(devices);
        return  pager;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("Failed to query device");
        return null;
    }
}

(2) New method definition for DeviceService

/**
 * Search device
 * @param page
 * @param pageSize
 * @param sn
 * @param tag
 * @return
 */
Pager<DeviceDTO> queryPage(Long page, Long pageSize, String sn, String tag, Integer status);

DeviceServiceImpl implementation method

@Override
public Pager<DeviceDTO> queryPage(Long page, Long pageSize, String sn, String tag, Integer status) {
    return  esRepository.searchDevice(page,pageSize,sn,tag,status);
}

(3) New method of DeviceController

/**
 * Paging search device
 * @param page
 * @param pageSize
 * @param sn
 * @param tag
 * @return
 */
@GetMapping
public Pager<DeviceDTO> findPage(@RequestParam(value = "page",required = false,defaultValue = "1") Long page,
                                 @RequestParam(value = "pageSize",required = false,defaultValue = "10") Long pageSize,
                                 @RequestParam(value = "sn",required = false) String sn,
                                 @RequestParam(value = "tag",required = false) String tag){
    return deviceService.queryPage(page,pageSize,sn,tag,null);
}

Topics: AI IoT