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 SYSTEM_STATUS_INFO_CACHE_MAP = new ConcurrentHashMap<>(); /** 终端状态 设备序列号_终端编号:在线状态:0:未知;1:在线;2:离线 */ private final static Map CAMERA_STATUS_INFO_CACHE_MAP = new ConcurrentHashMap<>(); /** 设备序列号:最近更新时间 */ private final static Map 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 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 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 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 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); } } } }