123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- 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<Device> deviceCollection = deviceManagerService.getAllDevicesFromCache();
- List<Device> 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<Device> deviceCollection = deviceManagerService.getAllDevicesFromCache();
- List<Device> 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<Device> deviceCollection = deviceManagerService.getAllDevicesFromCache();
- List<Device> 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<Device> deviceCollection = deviceManagerService.getAllDevicesFromCache();
- List<Device> 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);
- }
- }
- }
|