package com.hfln.device.application.task; import com.hfln.device.domain.entity.Device; import com.hfln.device.domain.gateway.DeviceGateway; import com.hfln.device.domain.gateway.MqttGateway; import com.hfln.device.domain.service.DeviceManagerService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.Collection; import java.util.Collections; import java.util.ArrayList; import java.util.List; /** * 设备状态检查任务 * 参考Python版本的check_dev_keepalive和check_dev_alarm_ack功能 */ @Component @Slf4j public class DeviceStatusCheckTask { @Autowired private DeviceManagerService deviceManagerService; @Autowired private DeviceGateway deviceGateway; @Autowired private MqttGateway mqttGateway; /** * 检查设备保活状态 (参考Python版本的check_dev_keepalive函数) * 每30秒执行一次 */ @Scheduled(fixedRate = 30000) // 30秒检查一次 public void checkDeviceKeepAlive() { try { long currentTime = System.currentTimeMillis(); Collection deviceCollection = deviceManagerService.getAllDevicesFromCache(); List allDevices = new ArrayList<>(deviceCollection); for (Device device : allDevices) { // 检查在线设备是否超时 if (Integer.valueOf(1).equals(device.getOnline()) && device.isExpired(currentTime)) { log.info("设备保活超时,设置为离线: deviceId={}, lastKeepAlive={}, currentTime={}", device.getDevId(), device.getKeepaliveTime(), currentTime); // 设置设备离线 device.updateOnlineStatus(0); // 更新数据库在线状态 deviceGateway.updateDeviceOnlineStatus(device.getDevId(), 0); // 更新设备缓存 deviceManagerService.updateDeviceInCache(device); // 发送设备状态更新消息 mqttGateway.sendDeviceStatusMessage(device); } } } catch (Exception e) { log.error("检查设备保活状态异常", e); } } /** * 检查设备告警确认状态 (参考Python版本的check_dev_alarm_ack函数) * 每分钟执行一次 */ @Scheduled(fixedRate = 60000) // 60秒检查一次 public void checkDeviceAlarmAck() { try { long currentTime = System.currentTimeMillis(); Collection deviceCollection = deviceManagerService.getAllDevicesFromCache(); List allDevices = new ArrayList<>(deviceCollection); for (Device device : allDevices) { // 检查告警确认是否超时 if (device.shouldClearAlarmAck(currentTime)) { log.info("告警确认超时,清除确认状态: deviceId={}, currentTime={}", device.getDevId(), currentTime); // 清除告警确认状态 device.clearAlarmAck(); // 更新设备缓存 deviceManagerService.updateDeviceInCache(device); } } } catch (Exception e) { log.error("检查设备告警确认状态异常", e); } } /** * 检查所有设备停留时间 (参考Python版本的check_all_dev_stay_time函数) * 每30秒执行一次 */ @Scheduled(fixedRate = 30000) // 30秒检查一次 public void checkAllDeviceStayTime() { try { long currentTime = System.currentTimeMillis(); Collection deviceCollection = deviceManagerService.getAllDevicesFromCache(); List allDevices = new ArrayList<>(deviceCollection); for (Device device : allDevices) { // 检查停留时间 Device.StayTimeRecord stayRecord = device.checkStayTime(currentTime); if (stayRecord != null) { log.info("检测到停留事件: deviceId={}, stayTime={}秒", device.getDevId(), stayRecord.getStayTime() / 1000); // 记录停留时间到数据库 recordStayTime(stayRecord); // 如果需要告警,创建滞留告警 if (stayRecord.isNeedAlarm()) { createRetentionAlarm(stayRecord); } // 更新设备缓存 deviceManagerService.updateDeviceInCache(device); } } } catch (Exception e) { log.error("检查设备停留时间异常", e); } } /** * 检查所有设备告警计划 (参考Python版本的check_all_dev_alarm_plan函数) * 每分钟执行一次 */ @Scheduled(fixedRate = 60000) // 60秒检查一次 public void checkAllDeviceAlarmPlan() { try { Collection deviceCollection = deviceManagerService.getAllDevicesFromCache(); List allDevices = new ArrayList<>(deviceCollection); for (Device device : allDevices) { // 检查设备的告警计划 device.checkAlarmPlans(); // 更新设备缓存 deviceManagerService.updateDeviceInCache(device); } } catch (Exception e) { log.error("检查设备告警计划异常", e); } } /** * 记录停留时间到数据库 */ private void recordStayTime(Device.StayTimeRecord stayRecord) { try { // 格式化停留时间 long stayTimeSeconds = stayRecord.getStayTime() / 1000; long hours = stayTimeSeconds / 3600; long minutes = (stayTimeSeconds % 3600) / 60; long seconds = stayTimeSeconds % 60; String stayTimeStr = String.format("%d时%d分%d秒", hours, minutes, seconds); // 调用网关记录停留时间 deviceGateway.recordDeviceStayTime( stayRecord.getDevId(), stayRecord.getEnterTime(), stayRecord.getLeaveTime(), stayTimeStr ); } catch (Exception e) { log.error("记录停留时间异常: deviceId={}", stayRecord.getDevId(), e); } } /** * 创建滞留告警 */ private void createRetentionAlarm(Device.StayTimeRecord stayRecord) { try { long currentTime = System.currentTimeMillis(); // 调用网关记录滞留告警 deviceGateway.recordDeviceRetentionAlarm( stayRecord.getDevId(), currentTime, stayRecord.getAlarmType(), stayRecord.getAlarmDescription() ); // 发送告警事件消息 mqttGateway.sendAlarmEventMessage( stayRecord.getDevId(), stayRecord.getAlarmDescription(), "alarm_event", 0 // 表ID,这里用0表示新插入的记录 ); log.info("创建滞留告警: deviceId={}, alarmType={}", stayRecord.getDevId(), stayRecord.getAlarmType()); } catch (Exception e) { log.error("创建滞留告警异常: deviceId={}", stayRecord.getDevId(), e); } } }