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
Listing | data type | explain |
---|---|---|
id | int | Table primary key id, self incrementing |
login_name | varchar(50) | Login account |
password | varchar(60) | password |
type | tinyint | Type 1: Super administrator 2: ordinary users are currently reserved fields |
board | varchar(50) | Kanban list |
Indicator configuration table tb_quota
Listing | data type | explain |
---|---|---|
id | int | Table primary key id |
name | varchar(50) | Indicator name |
unit | varchar(20) | Index unit |
subject | varchar(50) | Message subject |
value_key | varchar(50) | Indicator value field |
sn_key | varchar(50) | Device ID field |
webhook | varchar(1000) | web hook |
value_type | varchar(10) | Indicator field type, Double, integer, Boolean |
reference_value | varchar(100) | reference value |
Alarm configuration table tb_alarm
Listing | data type | explain |
---|---|---|
id | int | Table primary key id, self incrementing |
name | varchar(50) | Alarm indicator name |
quota_id | int | Associated indicator name |
operator | varchar(10) | operator |
threshold | int | Alarm threshold |
level | int | Alarm level 1: general 2: severe |
cycle | int | Silence period (in minutes) |
webhook | varchar(1000) | web hook address |
Panel configuration table tb_board
Listing | data type | explain |
---|---|---|
id | int | Table primary key id, self incrementing |
admin_id | int | Administrator id |
name | varchar(50) | Kanban name |
quota | varchar(100) | index |
device | varchar(100) | equipment |
system | tinyint | Is it a system Kanban |
disable | tinyint | Do not display |
GPS configuration table tb_gps
Listing | data type | explain |
---|---|---|
id | bigint | Table primary key id |
subject | varchar(50) | Message subject |
sn_key | varchar(50) | Device ID field |
type | tinyint | Type (single field, double field) |
value_key | varchar(50) | Latitude and longitude field |
separation | varchar(10) | Longitude and latitude separator |
longitude | varchar(20) | Longitude field |
latitude | varchar(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
Listing | data type | explain |
---|---|---|
deviceId | keyword | Equipment number |
alarm | boolean | Alarm or not |
alarmName | keyword | Alarm name |
level | integer | Alarm level |
online | boolean | Online |
status | boolean | switch |
tag | keyword | label |
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); }