| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- package com.zksy.pressure.utils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.MediaType;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import org.springframework.web.client.RestTemplate;
- import java.util.Date;
- import java.util.Map;
- import java.util.Set;
- import java.util.concurrent.ConcurrentHashMap;
- /**
- * 设备离线检测定时任务
- * 通过 REST API 更新设备在线状态
- */
- @Component
- public class DeviceOfflineCheckTask {
- private static final Logger logger = LoggerFactory.getLogger(DeviceOfflineCheckTask.class);
- /** 设备最后接收数据时间 */
- public static ConcurrentHashMap<String, Date> deviceLastReceiveTimeMap = new ConcurrentHashMap<>();
- /** 已知离线设备集合,用于避免重复API调用 */
- private final Set<String> offlineDeviceSet = ConcurrentHashMap.newKeySet();
- @Autowired
- private RestTemplate restTemplate;
- /** 离线判定超时,单位:分钟,默认30分钟 */
- @Value("${device.offline.timeout-minutes:30}")
- private int offlineTimeoutMinutes;
- /** 检查间隔,单位:毫秒,默认5分钟 */
- @Scheduled(fixedRateString = "${device.offline.check-interval-ms:300000}")
- public void checkDeviceOffline() {
- Date now = new Date();
- long timeoutMs = (long) offlineTimeoutMinutes * 60 * 1000;
- for (Map.Entry<String, Date> entry : deviceLastReceiveTimeMap.entrySet()) {
- long diff = now.getTime() - entry.getValue().getTime();
- if (diff > timeoutMs) {
- // 只在设备不在离线集合中时才调用API
- if (offlineDeviceSet.add(entry.getKey())) {
- updateDeviceOnlineStatus(entry.getKey(), 0);
- logger.info("设备 {} 已离线(超过{}分钟未收到数据)", entry.getKey(), offlineTimeoutMinutes);
- }
- }
- }
- }
- /**
- * 标记设备在线(收到数据时调用)
- * 只在设备当前处于离线状态时才调用API
- */
- public void markDeviceOnline(String deviceCode) {
- if (offlineDeviceSet.remove(deviceCode)) {
- updateDeviceOnlineStatus(deviceCode, 1);
- logger.info("设备 {} 恢复在线", deviceCode);
- }
- }
- private void updateDeviceOnlineStatus(String deviceCode, int onlineStatus) {
- try {
- Map<String, Object> params = Map.of("deviceCode", deviceCode, "onlineStatus", onlineStatus);
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_JSON);
- HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
- restTemplate.postForObject("http://zk-api-service/equipmentStatus/updateOnlineStatus", request, Map.class);
- } catch (Exception e) {
- logger.error("更新设备在线状态失败: deviceCode={}, onlineStatus={}", deviceCode, onlineStatus, e);
- }
- }
- }
|