zxl
2026-03-25 74e332504d98caaf8fab951d7d24be762b169f49
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.tievd.jyz.handler;
 
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tievd.jyz.cache.DeviceCache;
import com.tievd.jyz.constants.SystemConstant;
import com.tievd.jyz.entity.Device;
import com.tievd.jyz.mapper.DeviceMapper;
import com.tievd.jyz.mqtt.dto.CameraDTO;
import com.tievd.jyz.mqtt.dto.HeartbeatStatusDTO;
import com.tievd.jyz.mqtt.dto.MqttParamDTO;
import com.tievd.jyz.mqtt.dto.SystemStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 网关状态处理类
 * @author timi
 */
@Slf4j
@Component
public class DeviceStatusHandler {
    /** 设备序列号:状态信息 */
    private final static Map<String,SystemStatusDTO> SYSTEM_STATUS_INFO_CACHE_MAP = new ConcurrentHashMap<>();
    /** 终端状态 设备序列号_终端编号:在线状态:0:未知;1:在线;2:离线 */
    private final static Map<String,String> CAMERA_STATUS_INFO_CACHE_MAP = new ConcurrentHashMap<>();
    /** 设备序列号:最近更新时间 */
    private final static Map<String,Long> STATUS_TIME_CACHE_MAP = new ConcurrentHashMap<>();
    /** 心跳超时时间 */
    private static Long heartbeatTimeout;
    @Autowired
    private DeviceMapper deviceMapper;
 
    @Value("${init.heartbeatThresholdTime:70000}")
    public void setHeartbeatTimeout(Long heartbeatTimeout){
        DeviceStatusHandler.heartbeatTimeout = heartbeatTimeout;
    }
 
    /**
     * 状态心跳处理流程
     * @param mqttParamDTO
     * @return
     */
    public static void heartbeat(MqttParamDTO<JSON> mqttParamDTO){
        String deviceSn = mqttParamDTO.getSn();
        Long updateTime = Long.parseLong(mqttParamDTO.getTime());
        HeartbeatStatusDTO heartbeatStatusDTO = JSONObject.toJavaObject(mqttParamDTO.getData(), HeartbeatStatusDTO.class);
        SYSTEM_STATUS_INFO_CACHE_MAP.put(deviceSn, heartbeatStatusDTO.getSystem());
        STATUS_TIME_CACHE_MAP.put(deviceSn,updateTime);
        List<CameraDTO> cameras  = heartbeatStatusDTO.getCamera();
        if(ObjectUtil.isNotNull(cameras)){
            for(CameraDTO cameraDTO :cameras){
                CAMERA_STATUS_INFO_CACHE_MAP.put(deviceSn+"_"+cameraDTO.getCode(),cameraDTO.getStatus());
            }
        }
    }
 
 
 
    /**
     * 获取设备心跳最近上报时间
     * @param deviceSn 设备序列号
     * @return 最近上报时间
     */
    public static Long getLastReportTime(String deviceSn){
        return STATUS_TIME_CACHE_MAP.get(deviceSn);
    }
 
    /**
     * 获取设备最近上报系统状态
     * @param deviceSn 设备序列号
     * @return 状态数据
     */
    public static SystemStatusDTO getStatusInfo(String deviceSn){
        return SYSTEM_STATUS_INFO_CACHE_MAP.get(deviceSn);
    }
 
 
    /**
     * 获取设备最近上报系统状态
     * @param deviceSn 设备序列号
     * @return 状态数据
     */
    public static String getCameraStatus(String deviceSn,String code){
        return CAMERA_STATUS_INFO_CACHE_MAP.get(deviceSn+"_"+code);
    }
    
    /**
     * 获取设备最近上报系统状态
     */
    public static Map<String, String> getCameraStatusMap(){
        return CAMERA_STATUS_INFO_CACHE_MAP;
    }
 
    /**
     * 获取设备是否在线
     * @param deviceSn 设备序列号
     * @return
     */
    private static byte onlineStatus(String deviceSn){
         Long lastUpdateTime = STATUS_TIME_CACHE_MAP.get(deviceSn);
         if(ObjectUtil.isNotNull(lastUpdateTime)){
            if((System.currentTimeMillis() - lastUpdateTime) < heartbeatTimeout){
                //小于超时时间
                return SystemConstant.DEVICE_ONLINE;
            }
         }
        return SystemConstant.DEVICE_OFFLINE;
    }
 
    /**
     * 网关状态定时更新
     */
    @Scheduled(fixedDelay = 60000L)
    public void deviceStatusUpdate(){
        List<Device> devices = DeviceCache.getDeviceList();
        for(Device device : devices){
            Byte status = onlineStatus(device.getSn());
            if(!status.equals(device.getStatus())){
                log.info("网关 {} 在线状态变化,当前状态:{}",device.getName(),status);
                device.setStatus(status);
                Device updateDevice = new Device();
                updateDevice.setId(device.getId());
                updateDevice.setStatus(status);
                deviceMapper.updateById(updateDevice);
            }
        }
    }
 
}