|
@@ -0,0 +1,1611 @@
|
|
|
|
+//package com.hfln.device.domain.entity;
|
|
|
|
+//
|
|
|
|
+//import com.hfln.device.domain.vo.BehaviorPattern;
|
|
|
|
+//import lombok.*;
|
|
|
|
+//import org.springframework.util.CollectionUtils;
|
|
|
|
+//
|
|
|
|
+//import java.util.*;
|
|
|
|
+//
|
|
|
|
+///**
|
|
|
|
+// * 设备实体类 - 聚合根(Aggregate Root)
|
|
|
|
+// *
|
|
|
|
+// * 作为聚合根,Device 封装了设备相关的业务属性、行为和不变性,
|
|
|
|
+// * 其生命周期内可包含多个子实体(如 Region)和值对象(如 InstallParam、TrackingRegion、NetworkInfo)。
|
|
|
|
+// */
|
|
|
|
+//@Getter
|
|
|
|
+//@Setter
|
|
|
|
+//@Builder
|
|
|
|
+//@NoArgsConstructor
|
|
|
|
+//@AllArgsConstructor
|
|
|
|
+//public class DeviceCache {
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设备ID
|
|
|
|
+// */
|
|
|
|
+// private String devId; // 设备ID
|
|
|
|
+// private String devType; // 设备类型
|
|
|
|
+// private String software; // 软件版本
|
|
|
|
+// private String hardware; // 硬件版本
|
|
|
|
+// private String bluVer; // 蓝牙版本
|
|
|
|
+//
|
|
|
|
+//// private NetworkInfo network; // 网络信息
|
|
|
|
+// private String ssid; // WIFI SSID
|
|
|
|
+// private String password; // WIFI 密码
|
|
|
|
+// private String ip; // IP地址
|
|
|
|
+//// private InstallParam installParam; // 安装参数
|
|
|
|
+//private String mountPlain; // 安装面
|
|
|
|
+// private Integer isCeiling; // 是否天花板安装
|
|
|
|
+// private Float height; // 安装高度
|
|
|
|
+//// private TrackingRegion trackingRegion; // 跟踪区域
|
|
|
|
+// private Integer startX; // 起始X
|
|
|
|
+// private Integer startY; // 起始Y
|
|
|
|
+// private Integer startZ; // 起始Z
|
|
|
|
+// private Integer stopX; // 终止X
|
|
|
|
+// private Integer stopY; // 终止Y
|
|
|
|
+// private Integer stopZ; // 终止Z
|
|
|
|
+//
|
|
|
|
+// private List<Float> targets; // 实时目标位置
|
|
|
|
+// // private List<Integer> realtimePose; // 实时姿态
|
|
|
|
+// //
|
|
|
|
+//// private Long enterTs; // 进入时间戳
|
|
|
|
+//// private Long leaveTs; // 离开时间戳
|
|
|
|
+//// private Long stayTime; // 停留时间
|
|
|
|
+//
|
|
|
|
+//// private Long retentionTime; // 滞留时间
|
|
|
|
+//// private Long retentionKeepTime; // 滞留保持时间
|
|
|
|
+//// private Long retentionAlarmTime; // 滞留告警时间
|
|
|
|
+//private Integer online; // 在线状态:0-离线,1-在线
|
|
|
|
+//
|
|
|
|
+// private Long keepaliveTime; // 最后一次心跳时间
|
|
|
|
+// private Long expireTime; // 超时时间(毫秒),默认90秒
|
|
|
|
+// private Boolean alarmAck; // 告警确认
|
|
|
|
+// private Long lastAlarmAckTime; // 最后告警确认时间
|
|
|
|
+// //
|
|
|
|
+// private Long lastReportFallTime; // 最后上报跌倒时间
|
|
|
|
+////
|
|
|
|
+//// private String lastAlarmType; // 最后一次告警类型
|
|
|
|
+//// private Long lastAlarmTime; // 最后一次告警时间
|
|
|
|
+//
|
|
|
|
+// // 跌倒状态记录 (对应Python版本的device.falling_)
|
|
|
|
+// private Integer falling_; // 当前跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
|
|
|
|
+//
|
|
|
|
+// // 告警间隔相关属性 (参考Python版本)
|
|
|
|
+// private Long alarmInterval; // 告警间隔时间(毫秒),默认30秒
|
|
|
|
+// private Long alarmAckInterval; // 告警确认间隔时间(毫秒),默认5分钟
|
|
|
|
+//
|
|
|
|
+// // 调试参数 (参考Python版本的g_dev_dbg_map)
|
|
|
|
+// private Map<String, Object> debugParams = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+//// // 姿态分析相关属性
|
|
|
|
+//// private PoseAnalysisResult lastPoseResult; // 最近一次姿态分析结果
|
|
|
|
+//// private Long lastPoseChangeTime; // 最近一次姿态变化时间
|
|
|
|
+//// private Map<Integer, Long> poseDurations; // 各姿态持续时间(姿态ID -> 持续时间毫秒)
|
|
|
|
+//// private Map<Integer, Float> poseDistribution; // 姿态分布(姿态ID -> 占比百分比)
|
|
|
|
+//
|
|
|
|
+//// // 行为分析相关属性
|
|
|
|
+//// private Long lastActivityDetectTime; // 最近一次活动检测时间
|
|
|
|
+//// private Long lastRestTime; // 最近一次休息时间
|
|
|
|
+//// private Long lastFallTime; // 最近一次跌倒时间
|
|
|
|
+//// private Integer currentActivityLevel; // 当前活动级别
|
|
|
|
+//// private Map<String, Long> areaRetentionTimes; // 各区域滞留时间(区域名称 -> 开始滞留时间毫秒)
|
|
|
|
+//
|
|
|
|
+//// // 历史行为模式记录
|
|
|
|
+//// private final List<BehaviorPattern> behaviorHistory = new ArrayList<>();
|
|
|
|
+////
|
|
|
|
+//// // 告警历史记录
|
|
|
|
+//// private final List<Alarm> alarmHistory = new ArrayList<>();
|
|
|
|
+////
|
|
|
|
+//// // 设备最近的活动记录
|
|
|
|
+//// private final Map<String, Long> lastActivityTime = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+// // 每个事件类型的最后跌倒时间 (对应Python版本的last_fall_time_)
|
|
|
|
+// private final Map<String, Long> lastFallTimeByEvent = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+//// // 告警计划管理
|
|
|
|
+//// private Map<String, AlarmPlan> alarmPlanMap = new HashMap<>();
|
|
|
|
+////
|
|
|
|
+//// // 区域管理
|
|
|
|
+//// private List<Region> regions = new ArrayList<>();
|
|
|
|
+//
|
|
|
|
+// // 完整的设备参数信息 (对应Python版本的param_)
|
|
|
|
+// private Map<String, Object> param = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+//// // 点云数据队列 (对应Python版本的put_cloud_points_que方法)
|
|
|
|
+//// private final Queue<List<List<Float>>> cloudPointsQueue = new LinkedList<>();
|
|
|
|
+//// private static final int MAX_CLOUD_POINTS_QUEUE_SIZE = 10; // 最大队列大小
|
|
|
|
+////
|
|
|
|
+//// private final ReentrantLock lock = new ReentrantLock();
|
|
|
|
+//
|
|
|
|
+//// /**
|
|
|
|
+//// * 告警计划
|
|
|
|
+//// */
|
|
|
|
+//// private Map<String, Object> alarmSchedule;
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 目标稳定器 - 对应Python版本的TargetStabilizer类
|
|
|
|
+// * 动态阈值调整的目标稳定算法
|
|
|
|
+// */
|
|
|
|
+//// private static class TargetStabilizer {
|
|
|
|
+//// private final java.util.Deque<List<Float>> targetList;
|
|
|
|
+//// private final float baseThreshold;
|
|
|
|
+////
|
|
|
|
+//// public TargetStabilizer(int queueLength, float baseThreshold) {
|
|
|
|
+//// this.targetList = new java.util.ArrayDeque<>(queueLength);
|
|
|
|
+//// this.baseThreshold = baseThreshold;
|
|
|
|
+//// }
|
|
|
|
+////
|
|
|
|
+//// /**
|
|
|
|
+//// * 优化目标点 (对应Python版本的optimize_target方法)
|
|
|
|
+//// * @param newTarget 新接收到的目标点 [x, y, z, snr]
|
|
|
|
+//// * @return 优化后的目标点
|
|
|
|
+//// */
|
|
|
|
+//// public List<Float> optimizeTarget(List<Float> newTarget) {
|
|
|
|
+//// if (targetList.isEmpty()) {
|
|
|
|
+//// return new ArrayList<>(newTarget);
|
|
|
|
+//// }
|
|
|
|
+////
|
|
|
|
+//// // 计算队列中点的平均值 (对应Python版本的avg_x, avg_y, avg_z计算)
|
|
|
|
+//// float avgX = 0.0f, avgY = 0.0f, avgZ = 0.0f;
|
|
|
|
+//// for (List<Float> target : targetList) {
|
|
|
|
+//// avgX += target.get(0);
|
|
|
|
+//// avgY += target.get(1);
|
|
|
|
+//// avgZ += target.get(2);
|
|
|
|
+//// }
|
|
|
|
+//// avgX /= targetList.size();
|
|
|
|
+//// avgY /= targetList.size();
|
|
|
|
+//// avgZ /= targetList.size();
|
|
|
|
+////
|
|
|
|
+//// // 动态阈值调整 (对应Python版本的dynamic_threshold计算)
|
|
|
|
+//// float dx = newTarget.get(0) - avgX;
|
|
|
|
+//// float dy = newTarget.get(1) - avgY;
|
|
|
|
+//// float distanceToAvg = (float) Math.sqrt(dx * dx + dy * dy);
|
|
|
|
+//// float dynamicThreshold = baseThreshold + (distanceToAvg * 0.3f);
|
|
|
|
+////
|
|
|
|
+//// // 如果与均值的偏差超过动态阈值,则平滑处理 (对应Python版本的平滑逻辑)
|
|
|
|
+//// if (distanceToAvg > dynamicThreshold) {
|
|
|
|
+//// float smoothedX = (newTarget.get(0) + avgX) / 2.0f;
|
|
|
|
+//// float smoothedY = (newTarget.get(1) + avgY) / 2.0f;
|
|
|
|
+//// float smoothedZ = (newTarget.get(1) + avgZ) / 2.0f; // 保持与Python版本完全一致,包括这个bug:使用newTarget.get(1)而不是get(2)
|
|
|
|
+////
|
|
|
|
+//// List<Float> optimizedTarget = new ArrayList<>();
|
|
|
|
+//// optimizedTarget.add(smoothedX);
|
|
|
|
+//// optimizedTarget.add(smoothedY);
|
|
|
|
+//// optimizedTarget.add(smoothedZ);
|
|
|
|
+//// return optimizedTarget;
|
|
|
|
+//// } else {
|
|
|
|
+//// return new ArrayList<>(newTarget);
|
|
|
|
+//// }
|
|
|
|
+//// }
|
|
|
|
+////
|
|
|
|
+//// /**
|
|
|
|
+//// * 更新目标列表 (对应Python版本的update_target_list方法)
|
|
|
|
+//// * @param newTarget 原始目标点 [x, y, z, snr]
|
|
|
|
+//// * @return 优化后的目标点
|
|
|
|
+//// */
|
|
|
|
+//// public List<Float> updateTargetList(List<Float> newTarget) {
|
|
|
|
+//// if (newTarget.size() < 3) {
|
|
|
|
+//// // 对应Python: LOGDBG(f"update_target_list error: invlid target:{new_target}")
|
|
|
|
+//// return new ArrayList<>(newTarget);
|
|
|
|
+//// }
|
|
|
|
+////
|
|
|
|
+//// List<Float> optimizedTarget = optimizeTarget(newTarget);
|
|
|
|
+////
|
|
|
|
+//// // 如果队列已满,移除最老的目标 (对应Python的deque maxlen行为)
|
|
|
|
+//// if (targetList.size() >= 10) { // queueLength
|
|
|
|
+//// targetList.removeFirst();
|
|
|
|
+//// }
|
|
|
|
+//// targetList.addLast(optimizedTarget);
|
|
|
|
+////
|
|
|
|
+//// return optimizedTarget;
|
|
|
|
+//// }
|
|
|
|
+//// }
|
|
|
|
+////
|
|
|
|
+//// // 目标稳定器实例 (对应Python版本device中的stabilizer)
|
|
|
|
+//// private TargetStabilizer stabilizer = new TargetStabilizer(10, 1.0f);
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 构造函数,设置默认值
|
|
|
|
+// * @param devId 设备ID
|
|
|
|
+// */
|
|
|
|
+// public DeviceCache(String devId) {
|
|
|
|
+// this.devId = devId;
|
|
|
|
+// this.online = 0;
|
|
|
|
+// this.expireTime = 90000L; // 默认90秒
|
|
|
|
+// this.alarmAck = false;
|
|
|
|
+// this.alarmInterval = 30000L; // 默认30秒告警间隔
|
|
|
|
+// this.alarmAckInterval = 300000L; // 默认5分钟告警确认间隔
|
|
|
|
+//// this.realtimePose = new ArrayList<>();
|
|
|
|
+//// this.poseDurations = new HashMap<>();
|
|
|
|
+//// this.poseDistribution = new HashMap<>();
|
|
|
|
+//// this.areaRetentionTimes = new HashMap<>();
|
|
|
|
+//// this.alarmPlanMap = new HashMap<>();
|
|
|
|
+//// this.regions = new ArrayList<>();
|
|
|
|
+// this.debugParams = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+//// // 初始化时间戳
|
|
|
|
+//// this.enterTs = -1L;
|
|
|
|
+//// this.leaveTs = -1L;
|
|
|
|
+//// this.stayTime = -1L;
|
|
|
|
+////
|
|
|
|
+//// // 初始化滞留相关参数 (参考Python版本)
|
|
|
|
+//// this.retentionTime = 60000L; // 默认60秒
|
|
|
|
+//// this.retentionKeepTime = 30000L; // 默认30秒
|
|
|
|
+//// this.retentionAlarmTime = 180000L; // 默认180秒(3分钟)
|
|
|
|
+//
|
|
|
|
+// // 初始化跌倒状态 (对应Python版本)
|
|
|
|
+// this.falling_ = 0; // 默认无跌倒状态
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 安装参数 - 值对象(Value Object)
|
|
|
|
+// * 不可变对象,描述设备的安装参数。
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// @Builder
|
|
|
|
+// public static class InstallParam {
|
|
|
|
+// private String mountPlain; // 安装面
|
|
|
|
+// private Integer isCeiling; // 是否天花板安装
|
|
|
|
+// private Float height; // 安装高度
|
|
|
|
+// private TrackingRegion trackingRegion; // 跟踪区域
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * TODO: 完善安装参数类,参考dev_mng.py中的InstallParam类
|
|
|
|
+// * 1. 添加安装面属性 (参考dev_mng.py中的mount_plain和isCeiling属性)
|
|
|
|
+// * 2. 完善跟踪区域属性 (参考dev_mng.py中的tracking_region属性)
|
|
|
|
+// */
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 跟踪区域 - 值对象(Value Object)
|
|
|
|
+// * 不可变对象,描述设备的跟踪区域。
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// public static class TrackingRegion {
|
|
|
|
+// private Integer startX; // 起始X
|
|
|
|
+// private Integer startY; // 起始Y
|
|
|
|
+// private Integer startZ; // 起始Z
|
|
|
|
+// private Integer stopX; // 终止X
|
|
|
|
+// private Integer stopY; // 终止Y
|
|
|
|
+// private Integer stopZ; // 终止Z
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * TODO: 完善跟踪区域类,参考dev_mng.py中的TrackingRegion类
|
|
|
|
+// * 1. 添加线程安全访问机制 (参考dev_mng.py中的lock_机制)
|
|
|
|
+// * 2. 完善区域属性 (参考dev_mng.py中的TrackingRegion类属性)
|
|
|
|
+// */
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 网络信息 - 值对象(Value Object)
|
|
|
|
+// * 不可变对象,描述设备的网络配置。
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// @Builder
|
|
|
|
+// public static class NetworkInfo {
|
|
|
|
+// private String ssid; // WIFI SSID
|
|
|
|
+// private String password; // WIFI 密码
|
|
|
|
+// private String ip; // IP地址
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * TODO: 完善网络信息类,参考dev_mng.py中的Network类
|
|
|
|
+// * 1. 添加线程安全访问机制 (参考dev_mng.py中的lock_机制)
|
|
|
|
+// * 2. 增加更多网络属性 (参考dev_mng.py中的Network类属性)
|
|
|
|
+// */
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 告警实体
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// @Builder
|
|
|
|
+// public static class Alarm {
|
|
|
|
+// private Long id; // 告警ID
|
|
|
|
+// private String type; // 告警类型
|
|
|
|
+// private String description; // 告警描述
|
|
|
|
+// private Integer severity; // 严重程度
|
|
|
|
+// private Long timestamp; // 时间戳
|
|
|
|
+// private Boolean acknowledged; // 是否已确认
|
|
|
|
+// private Long acknowledgedTime; // 确认时间
|
|
|
|
+// private Long userId; // 确认用户ID
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 确认告警
|
|
|
|
+// * @param userId 用户ID
|
|
|
|
+// * @param timestamp 确认时间
|
|
|
|
+// */
|
|
|
|
+// public void acknowledge(Long userId, Long timestamp) {
|
|
|
|
+// this.acknowledged = true;
|
|
|
|
+// this.acknowledgedTime = timestamp;
|
|
|
|
+// this.userId = userId;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新设备保活时间
|
|
|
|
+// * @param keepaliveTime 保活时间戳
|
|
|
|
+// */
|
|
|
|
+// public void updateKeepAliveTime(Long keepaliveTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.keepaliveTime = keepaliveTime;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新设备在线状态
|
|
|
|
+// * @param online 在线状态
|
|
|
|
+// * @return 返回旧的在线状态
|
|
|
|
+// */
|
|
|
|
+// public Integer updateOnlineStatus(Integer online) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// Integer oldStatus = this.online;
|
|
|
|
+// this.online = online;
|
|
|
|
+// return oldStatus;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新停留时间
|
|
|
|
+// */
|
|
|
|
+// public void updateStayTime() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// if (enterTs != null && leaveTs != null) {
|
|
|
|
+// stayTime = leaveTs - enterTs;
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 重置进入时间
|
|
|
|
+// */
|
|
|
|
+// public void resetEnterTs() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.enterTs = null;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 重置离开时间
|
|
|
|
+// */
|
|
|
|
+// public void resetLeaveTs() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.leaveTs = null;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 重置停留时间
|
|
|
|
+// */
|
|
|
|
+// public void resetStayTime() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.stayTime = 0L;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查设备是否超时
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return 是否超时
|
|
|
|
+// */
|
|
|
|
+// public boolean isExpired(long currentTime) {
|
|
|
|
+// if (online != null && online == 1 && keepaliveTime != null && expireTime != null) {
|
|
|
|
+// return (currentTime - keepaliveTime) > expireTime;
|
|
|
|
+// }
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置告警确认状态
|
|
|
|
+// * @param ack 确认状态
|
|
|
|
+// * @param timestamp 确认时间
|
|
|
|
+// */
|
|
|
|
+// public void setAlarmAcknowledgement(boolean ack, long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.alarmAck = ack;
|
|
|
|
+// this.lastAlarmAckTime = timestamp;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置最后上报跌倒时间 (对应Python版本的set_last_report_fall_time方法)
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void setLastReportFallTime(Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.lastReportFallTime = timestamp;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取最后上报跌倒时间 (对应Python版本的last_report_fall_time方法)
|
|
|
|
+// * @return 最后上报跌倒时间
|
|
|
|
+// */
|
|
|
|
+// public Long getLastReportFallTime() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return lastReportFallTime != null ? lastReportFallTime : 0L;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 添加告警记录
|
|
|
|
+// * @param alarm 告警对象
|
|
|
|
+// */
|
|
|
|
+// public void addAlarm(Alarm alarm) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// alarmHistory.add(alarm);
|
|
|
|
+// lastAlarmType = alarm.getType();
|
|
|
|
+// lastAlarmTime = alarm.getTimestamp();
|
|
|
|
+//
|
|
|
|
+// // 更新最近活动时间
|
|
|
|
+// updateLastActivityTime(alarm.getType(), alarm.getTimestamp());
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 添加行为模式
|
|
|
|
+// * @param pattern 行为模式
|
|
|
|
+// */
|
|
|
|
+// public void addBehaviorPattern(BehaviorPattern pattern) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// behaviorHistory.add(pattern);
|
|
|
|
+//
|
|
|
|
+// // 如果是异常行为,更新相关状态
|
|
|
|
+// if (pattern.getBehaviorType() != null &&
|
|
|
|
+// pattern.getBehaviorType() == 3) { // 3表示异常行为
|
|
|
|
+//
|
|
|
|
+// // 更新最近活动时间
|
|
|
|
+// updateLastActivityTime(pattern.getDescription(), pattern.getTimestamp());
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新最近活动时间
|
|
|
|
+// * @param activityType 活动类型
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// private void updateLastActivityTime(String activityType, Long timestamp) {
|
|
|
|
+// if (activityType != null && timestamp != null) {
|
|
|
|
+// lastActivityTime.put(activityType, timestamp);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 确认告警
|
|
|
|
+// * @param alarmId 告警ID
|
|
|
|
+// * @param userId 用户ID
|
|
|
|
+// * @param timestamp 确认时间
|
|
|
|
+// * @return 是否成功确认
|
|
|
|
+// */
|
|
|
|
+// public boolean acknowledgeAlarm(Long alarmId, Long userId, Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// for (Alarm alarm : alarmHistory) {
|
|
|
|
+// if (alarm.getId() != null && alarm.getId().equals(alarmId)) {
|
|
|
|
+// alarm.acknowledge(userId, timestamp);
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// return false;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取未确认的告警
|
|
|
|
+// * @return 未确认的告警列表
|
|
|
|
+// */
|
|
|
|
+// public List<Alarm> getUnacknowledgedAlarms() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// List<Alarm> unacknowledgedAlarms = new ArrayList<>();
|
|
|
|
+// for (Alarm alarm : alarmHistory) {
|
|
|
|
+// if (alarm.getAcknowledged() == null || !alarm.getAcknowledged()) {
|
|
|
|
+// unacknowledgedAlarms.add(alarm);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// return unacknowledgedAlarms;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查是否应该发送告警
|
|
|
|
+// * @param alarmType 告警类型
|
|
|
|
+// * @param timestamp 当前时间戳
|
|
|
|
+// * @param intervalThreshold 告警间隔阈值(毫秒)
|
|
|
|
+// * @return 是否应该发送告警
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldSendAlarm(String alarmType, Long timestamp, Long intervalThreshold) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// // 如果没有最近活动记录,应该发送告警
|
|
|
|
+// if (!lastActivityTime.containsKey(alarmType)) {
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 获取上次该类型告警的时间
|
|
|
|
+// Long lastTime = lastActivityTime.get(alarmType);
|
|
|
|
+// if (lastTime == null) {
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 检查告警间隔是否超过阈值
|
|
|
|
+// return (timestamp - lastTime) > intervalThreshold;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查设备是否存在持续滞留
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @param areaName 区域名称
|
|
|
|
+// * @param retentionThreshold 滞留阈值(毫秒)
|
|
|
|
+// * @return 是否滞留
|
|
|
|
+// */
|
|
|
|
+// public boolean checkRetention(Long currentTime, String areaName, Long retentionThreshold) {
|
|
|
|
+// if (enterTs == null || currentTime == null) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// long stayDuration = currentTime - enterTs;
|
|
|
|
+//
|
|
|
|
+// // 如果滞留时间超过阈值且未发送过滞留告警,则需要发送告警
|
|
|
|
+// if (stayDuration > retentionThreshold) {
|
|
|
|
+// // 如果没有发送过滞留告警或者距离上次告警时间已经超过阈值
|
|
|
|
+// if (retentionAlarmTime == null || (currentTime - retentionAlarmTime) > retentionThreshold) {
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新设备姿态
|
|
|
|
+// *
|
|
|
|
+// * @param pose 姿态
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void updatePose(Integer pose, Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// // 检查姿态是否变化
|
|
|
|
+// boolean poseChanged = false;
|
|
|
|
+// if (realtimePose == null) {
|
|
|
|
+// realtimePose = new ArrayList<>();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// if (realtimePose.isEmpty() || !pose.equals(realtimePose.get(0))) {
|
|
|
|
+// poseChanged = true;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 添加新姿态到列表开头
|
|
|
|
+// realtimePose.add(0, pose);
|
|
|
|
+//
|
|
|
|
+// // 保持列表长度不超过10
|
|
|
|
+// if (realtimePose.size() > 10) {
|
|
|
|
+// realtimePose.remove(realtimePose.size() - 1);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 如果姿态发生变化,更新姿态变化时间
|
|
|
|
+// if (poseChanged) {
|
|
|
|
+// lastPoseChangeTime = timestamp;
|
|
|
|
+//
|
|
|
|
+// // 更新姿态持续时间
|
|
|
|
+// updatePoseDuration(pose, timestamp);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新姿态持续时间
|
|
|
|
+// *
|
|
|
|
+// * @param pose 姿态
|
|
|
|
+// * @param timestamp 当前时间戳
|
|
|
|
+// */
|
|
|
|
+// private void updatePoseDuration(Integer pose, Long timestamp) {
|
|
|
|
+// if (poseDurations == null) {
|
|
|
|
+// poseDurations = new HashMap<>();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 初始化姿态持续时间
|
|
|
|
+// if (!poseDurations.containsKey(pose)) {
|
|
|
|
+// poseDurations.put(pose, 0L);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新区域滞留时间
|
|
|
|
+// *
|
|
|
|
+// * @param areaName 区域名称
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void updateAreaRetentionTime(String areaName, Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (areaRetentionTimes == null) {
|
|
|
|
+// areaRetentionTimes = new HashMap<>();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 记录区域滞留开始时间
|
|
|
|
+// if (!areaRetentionTimes.containsKey(areaName)) {
|
|
|
|
+// areaRetentionTimes.put(areaName, timestamp);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 重置区域滞留时间
|
|
|
|
+// *
|
|
|
|
+// * @param areaName 区域名称
|
|
|
|
+// */
|
|
|
|
+// public void resetAreaRetentionTime(String areaName) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (areaRetentionTimes != null && areaRetentionTimes.containsKey(areaName)) {
|
|
|
|
+// areaRetentionTimes.remove(areaName);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取区域滞留时间
|
|
|
|
+// *
|
|
|
|
+// * @param areaName 区域名称
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return 滞留时间(毫秒)
|
|
|
|
+// */
|
|
|
|
+// public Long getAreaRetentionDuration(String areaName, Long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (areaRetentionTimes == null || !areaRetentionTimes.containsKey(areaName)) {
|
|
|
|
+// return 0L;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// Long startTime = areaRetentionTimes.get(areaName);
|
|
|
|
+// if (startTime == null) {
|
|
|
|
+// return 0L;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return currentTime - startTime;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 添加告警计划
|
|
|
|
+// *
|
|
|
|
+// * @param alarmPlan 告警计划
|
|
|
|
+// */
|
|
|
|
+// public void addAlarmPlan(AlarmPlan alarmPlan) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (alarmPlan != null && alarmPlan.getName() != null) {
|
|
|
|
+// alarmPlanMap.put(alarmPlan.getName(), alarmPlan);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 移除告警计划
|
|
|
|
+// *
|
|
|
|
+// * @param planName 计划名称
|
|
|
|
+// * @return 被移除的告警计划
|
|
|
|
+// */
|
|
|
|
+// public AlarmPlan removeAlarmPlan(String planName) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// return alarmPlanMap.remove(planName);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取告警计划
|
|
|
|
+// *
|
|
|
|
+// * @param planName 计划名称
|
|
|
|
+// * @return 告警计划
|
|
|
|
+// */
|
|
|
|
+// public AlarmPlan getAlarmPlan(String planName) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// return alarmPlanMap.get(planName);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取所有告警计划
|
|
|
|
+// *
|
|
|
|
+// * @return 告警计划列表
|
|
|
|
+// */
|
|
|
|
+// public List<AlarmPlan> getAllAlarmPlans() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// return new ArrayList<>(alarmPlanMap.values());
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新告警计划目标
|
|
|
|
+// *
|
|
|
|
+// * @param targets 目标点列表
|
|
|
|
+// */
|
|
|
|
+// public void updateAlarmTargets(List<List<Float>> targets) {
|
|
|
|
+// if (targets == null || targets.isEmpty()) {
|
|
|
|
+// return;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// long currentTime = System.currentTimeMillis();
|
|
|
|
+//
|
|
|
|
+// // 更新所有告警计划的目标
|
|
|
|
+// if (CollectionUtils.isEmpty(alarmPlanMap)) {
|
|
|
|
+// return;
|
|
|
|
+// }
|
|
|
|
+// for (AlarmPlan plan : alarmPlanMap.values()) {
|
|
|
|
+// plan.updateTarget(targets, currentTime);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查所有告警计划
|
|
|
|
+// *
|
|
|
|
+// * @return 需要触发告警的计划列表
|
|
|
|
+// */
|
|
|
|
+// public List<AlarmPlan> checkAlarmPlans() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// List<AlarmPlan> alarmedPlans = new ArrayList<>();
|
|
|
|
+// long currentTime = System.currentTimeMillis();
|
|
|
|
+//
|
|
|
|
+// // 检查所有告警计划
|
|
|
|
+// for (AlarmPlan plan : alarmPlanMap.values()) {
|
|
|
|
+// if (plan.checkRetention(currentTime)) {
|
|
|
|
+// alarmedPlans.add(plan);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return alarmedPlans;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 添加区域
|
|
|
|
+// *
|
|
|
|
+// * @param region 区域
|
|
|
|
+// */
|
|
|
|
+// public void addRegion(Region region) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (region != null) {
|
|
|
|
+// // 检查是否已存在相同ID的区域
|
|
|
|
+// for (int i = 0; i < regions.size(); i++) {
|
|
|
|
+// if (regions.get(i).getId().equals(region.getId())) {
|
|
|
|
+// // 更新现有区域
|
|
|
|
+// regions.set(i, region);
|
|
|
|
+// return;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 添加新区域
|
|
|
|
+// regions.add(region);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 移除区域
|
|
|
|
+// *
|
|
|
|
+// * @param regionId 区域ID
|
|
|
|
+// * @return 是否成功移除
|
|
|
|
+// */
|
|
|
|
+// public boolean removeRegion(String regionId) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// for (int i = 0; i < regions.size(); i++) {
|
|
|
|
+// if (regions.get(i).getId().equals(regionId)) {
|
|
|
|
+// regions.remove(i);
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return false;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取区域
|
|
|
|
+// *
|
|
|
|
+// * @param regionId 区域ID
|
|
|
|
+// * @return 区域
|
|
|
|
+// */
|
|
|
|
+// public Region getRegion(String regionId) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// for (Region region : regions) {
|
|
|
|
+// if (region.getId().equals(regionId)) {
|
|
|
|
+// return region;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return null;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取所有区域
|
|
|
|
+// *
|
|
|
|
+// * @return 区域列表
|
|
|
|
+// */
|
|
|
|
+// public List<Region> getAllRegions() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// return new ArrayList<>(regions);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 查找包含指定点的区域
|
|
|
|
+// *
|
|
|
|
+// * @param x 点的x坐标
|
|
|
|
+// * @param y 点的y坐标
|
|
|
|
+// * @return 包含该点的区域列表
|
|
|
|
+// */
|
|
|
|
+// public List<Region> findRegionsContainingPoint(float x, float y) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// List<Region> result = new ArrayList<>();
|
|
|
|
+//
|
|
|
|
+// for (Region region : regions) {
|
|
|
|
+// if (region.containsPoint(x, y)) {
|
|
|
|
+// result.add(region);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return result;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新告警配置
|
|
|
|
+// *
|
|
|
|
+// * @param retentionTime 停留时间阈值(毫秒)
|
|
|
|
+// * @param retentionKeepTime 停留保持时间(毫秒)
|
|
|
|
+// * @param retentionAlarmTime 停留告警时间(毫秒)
|
|
|
|
+// */
|
|
|
|
+// public void updateAlarmConfig(long retentionTime, long retentionKeepTime, long retentionAlarmTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.retentionTime = retentionTime;
|
|
|
|
+// this.retentionKeepTime = retentionKeepTime;
|
|
|
|
+// this.retentionAlarmTime = retentionAlarmTime;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查是否应该发送跌倒告警 (参考Python版本的deal_report_falling_event逻辑)
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return true如果应该发送告警
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldSendFallAlarm(long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// // 检查告警确认状态
|
|
|
|
+// if (Boolean.TRUE.equals(alarmAck)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 检查告警间隔
|
|
|
|
+// if (lastReportFallTime != null) {
|
|
|
|
+// long timeSinceLastAlarm = currentTime - lastReportFallTime;
|
|
|
|
+// if (timeSinceLastAlarm < alarmInterval) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return true;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查心跳是否被调试参数拒绝 (参考Python版本的deal_dev_keepalive逻辑)
|
|
|
|
+// * @return true如果应该拒绝心跳
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldRejectKeepAlive() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// Object keepaliveDebug = debugParams.get("keepalive");
|
|
|
|
+// return keepaliveDebug != null && Integer.valueOf(0).equals(keepaliveDebug);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置设备参数信息
|
|
|
|
+// * 对应Python版本的set_param(self, param)方法
|
|
|
|
+// * @param param 完整的设备参数信息
|
|
|
|
+// */
|
|
|
|
+// public void setParam(Map<String, Object> param) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.param = param;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取设备参数信息
|
|
|
|
+// * 对应Python版本的param(self)方法
|
|
|
|
+// * @return 完整的设备参数信息
|
|
|
|
+// */
|
|
|
|
+// public Map<String, Object> getParam() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return param;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置调试参数
|
|
|
|
+// * @param key 参数键
|
|
|
|
+// * @param value 参数值
|
|
|
|
+// */
|
|
|
|
+// public void setDebugParam(String key, Object value) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// debugParams.put(key, value);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取调试参数
|
|
|
|
+// * @param key 参数键
|
|
|
|
+// * @return 参数值
|
|
|
|
+// */
|
|
|
|
+// public Object getDebugParam(String key) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return debugParams.get(key);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查停留时间并处理滞留告警 (参考Python版本的check_stay_time逻辑)
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return 如果检测到滞留事件返回滞留记录,否则返回null
|
|
|
|
+// */
|
|
|
|
+// public StayTimeRecord checkStayTime(long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// if (enterTs == null || enterTs == -1 || leaveTs == null || leaveTs == -1) {
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 保留时间内,不认为停留事件结束
|
|
|
|
+// long timeSinceLeave = currentTime - leaveTs;
|
|
|
|
+// if (timeSinceLeave <= retentionKeepTime) {
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 时间少于最小时间尺,忽略本次事件,并重置计时
|
|
|
|
+// long stayTimeMs = leaveTs - enterTs;
|
|
|
|
+// if (stayTimeMs < retentionTime) {
|
|
|
|
+// // 重置计时
|
|
|
|
+// this.enterTs = -1L;
|
|
|
|
+// this.leaveTs = -1L;
|
|
|
|
+// this.stayTime = -1L;
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 创建停留时间记录
|
|
|
|
+// StayTimeRecord record = new StayTimeRecord();
|
|
|
|
+// record.setDevId(devId);
|
|
|
|
+// record.setEnterTime(enterTs);
|
|
|
|
+// record.setLeaveTime(leaveTs);
|
|
|
|
+// record.setStayTime(stayTimeMs);
|
|
|
|
+//
|
|
|
|
+// // 检查是否需要创建滞留告警 (超过3分钟视为异常滞留)
|
|
|
|
+// long stayTimeSeconds = stayTimeMs / 1000;
|
|
|
|
+// if (stayTimeSeconds >= (retentionAlarmTime / 1000)) {
|
|
|
|
+// record.setNeedAlarm(true);
|
|
|
|
+// record.setAlarmType("alarm_retention");
|
|
|
|
+// record.setAlarmDescription("设备滞留时间过长");
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 重置计时
|
|
|
|
+// this.enterTs = -1L;
|
|
|
|
+// this.leaveTs = -1L;
|
|
|
|
+// this.stayTime = -1L;
|
|
|
|
+//
|
|
|
|
+// return record;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查告警确认是否超时 (参考Python版本的check_dev_alarm_ack逻辑)
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return true如果告警确认超时需要清除
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldClearAlarmAck(long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// if (Boolean.TRUE.equals(alarmAck) && lastAlarmAckTime != null) {
|
|
|
|
+// long timeSinceAck = currentTime - lastAlarmAckTime;
|
|
|
|
+// return timeSinceAck > alarmAckInterval;
|
|
|
|
+// }
|
|
|
|
+// return false;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 清除告警确认状态
|
|
|
|
+// */
|
|
|
|
+// public void clearAlarmAck() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.alarmAck = false;
|
|
|
|
+// this.lastAlarmAckTime = null;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 更新实时位置(平滑算法) - 重写以对应Python版本的update_targets方法
|
|
|
|
+// * @param newTargets 新的目标位置列表
|
|
|
|
+// * @return 稳定的目标位置列表
|
|
|
|
+// */
|
|
|
|
+// public List<List<Float>> updateTargets(List<List<Float>> newTargets) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// // 对应Python版本的输入验证
|
|
|
|
+// if (newTargets == null || newTargets.isEmpty() ||
|
|
|
|
+// newTargets.get(0).size() < 3) {
|
|
|
|
+// // 对应Python: LOGERR(f"update_targets error: invalid new_targets")
|
|
|
|
+// return new ArrayList<>();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 对应Python: new_target = new_targets[0]
|
|
|
|
+// List<Float> newTarget = newTargets.get(0);
|
|
|
|
+//
|
|
|
|
+// // 对应Python: stable_target = self.stabilizer.update_target_list(new_target)
|
|
|
|
+// List<Float> stableTarget = stabilizer.updateTargetList(newTarget);
|
|
|
|
+//
|
|
|
|
+// // 更新targets字段
|
|
|
|
+// this.targets = stableTarget;
|
|
|
|
+//
|
|
|
|
+// // 对应Python: return [stable_target]
|
|
|
|
+// List<List<Float>> result = new ArrayList<>();
|
|
|
|
+// result.add(stableTarget);
|
|
|
|
+// return result;
|
|
|
|
+//
|
|
|
|
+// } catch (Exception e) {
|
|
|
|
+// // 对应Python: except Exception as e: LOGERR(f"update_targets error: {e}")
|
|
|
|
+// return new ArrayList<>();
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取实时姿态 (对应Python版本的realtime_pose方法)
|
|
|
|
+// * @return 实时姿态列表
|
|
|
|
+// */
|
|
|
|
+// public List<Integer> getRealtimePose() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return realtimePose != null ? new ArrayList<>(realtimePose) : new ArrayList<>();
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置实时姿态 (对应Python版本的set_realtime_pose方法)
|
|
|
|
+// * @param pose 姿态列表
|
|
|
|
+// */
|
|
|
|
+// public void setRealtimePose(List<Integer> pose) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.realtimePose = pose != null ? new ArrayList<>(pose) : new ArrayList<>();
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取进入时间 (对应Python版本的enter_ts方法)
|
|
|
|
+// * @return 进入时间戳,如果未设置返回-1
|
|
|
|
+// */
|
|
|
|
+// public Long getEnterTime() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return enterTs != null ? enterTs : -1L;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置进入时间 (对应Python版本的set_enter_ts方法)
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void setEnterTime(Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.enterTs = timestamp;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取离开时间 (对应Python版本的leave_ts方法)
|
|
|
|
+// * @return 离开时间戳,如果未设置返回-1
|
|
|
|
+// */
|
|
|
|
+// public Long getLeaveTime() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return leaveTs != null ? leaveTs : -1L;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置离开时间 (对应Python版本的set_leave_ts方法)
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void setLeaveTime(Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.leaveTs = timestamp;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查告警间隔 (对应Python版本的告警间隔检查逻辑)
|
|
|
|
+// * @param eventType 事件类型
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return 是否应该发送告警
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldSendAlarmForEvent(String eventType, Long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// // 如果已经确认告警,则不发送
|
|
|
|
+// if (Boolean.TRUE.equals(alarmAck)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 检查告警间隔 (对应Python: now - device.last_fall_time(event) < device.alarm_interval())
|
|
|
|
+// Long lastEventTime = lastFallTimeByEvent.get(eventType);
|
|
|
|
+// if (lastEventTime != null && currentTime != null) {
|
|
|
|
+// long timeSinceLastAlarm = currentTime - lastEventTime;
|
|
|
|
+// return timeSinceLastAlarm >= (alarmInterval != null ? alarmInterval : 30000L); // 默认30秒间隔
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return true;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置最后跌倒时间 (对应Python版本的set_last_fall_time方法)
|
|
|
|
+// * @param eventType 事件类型
|
|
|
|
+// * @param timestamp 时间戳
|
|
|
|
+// */
|
|
|
|
+// public void setLastFallTime(String eventType, Long timestamp) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.lastReportFallTime = timestamp;
|
|
|
|
+// // 为每个事件类型单独记录时间 (对应Python版本的last_fall_time_[event] = time)
|
|
|
|
+// lastFallTimeByEvent.put(eventType, timestamp);
|
|
|
|
+// lastActivityTime.put("fall_" + eventType, timestamp);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取指定事件类型的最后跌倒时间 (对应Python版本的last_fall_time(event))
|
|
|
|
+// * @param eventType 事件类型
|
|
|
|
+// * @return 最后跌倒时间,如果没有记录返回0
|
|
|
|
+// */
|
|
|
|
+// public Long getLastFallTime(String eventType) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return lastFallTimeByEvent.getOrDefault(eventType, 0L);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取当前跌倒状态 (对应Python版本的device.falling_)
|
|
|
|
+// * @return 跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
|
|
|
|
+// */
|
|
|
|
+// public Integer getFalling() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return falling_ != null ? falling_ : 0;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置当前跌倒状态 (对应Python版本的device.falling_)
|
|
|
|
+// * @param falling 跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
|
|
|
|
+// */
|
|
|
|
+// public void setFalling(Integer falling) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// this.falling_ = falling;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查LNA设备的告警间隔 (对应Python版本的LNA特殊逻辑)
|
|
|
|
+// *
|
|
|
|
+// * Python真实逻辑:
|
|
|
|
+// * - device.falling_字段永远为0(从不更新)
|
|
|
|
+// * - 当falling==0(无跌倒)时:falling_ == falling为true,检查报警间隔
|
|
|
|
+// * - 当falling!=0(有跌倒)时:falling_ == falling为false,跳过报警间隔检查,立即发送
|
|
|
|
+// * - 简化理解:只有无跌倒状态才检查报警间隔,任何跌倒状态都立即发送
|
|
|
|
+// *
|
|
|
|
+// * @param newFalling 新的跌倒状态
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return 是否应该发送告警
|
|
|
|
+// */
|
|
|
|
+// public boolean shouldSendAlarmForLNA(Integer newFalling, Long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// // 如果已经确认告警,则不发送
|
|
|
|
+// if (Boolean.TRUE.equals(alarmAck)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 对应Python逻辑:if device.falling_ == falling
|
|
|
|
+// // 由于falling_永远为0,所以只有当newFalling==0时才检查报警间隔
|
|
|
|
+// if (Objects.equals(falling_, newFalling)) {
|
|
|
|
+// // 检查报警间隔(使用lastReportFallTime,对应Python: device.last_report_fall_time())
|
|
|
|
+// if (lastReportFallTime != null && currentTime != null) {
|
|
|
|
+// long timeSinceLastAlarm = currentTime - lastReportFallTime;
|
|
|
|
+// return timeSinceLastAlarm >= (alarmInterval != null ? alarmInterval : 30000L);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 当falling_不等于newFalling时(即newFalling!=0时),或者没有历史时间时,直接发送
|
|
|
|
+// return true;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 根据设备类型处理跌倒事件 (参考Python版本的设备类型区分逻辑)
|
|
|
|
+// * @param event 事件类型
|
|
|
|
+// * @param pose 姿态
|
|
|
|
+// * @param location 位置坐标
|
|
|
|
+// * @return 处理结果
|
|
|
|
+// */
|
|
|
|
+// public FallEventResult processFallEvent(String event, int pose, List<Float> location) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// FallEventResult result = new FallEventResult();
|
|
|
|
+// result.setDevId(devId);
|
|
|
|
+// result.setEvent(event);
|
|
|
|
+//
|
|
|
|
+// if ("LNB".equals(devType)) {
|
|
|
|
+// // LNB设备的处理逻辑 (参考Python版本)
|
|
|
|
+// result.setPose("no_fall".equals(event) ? 4 : 0); // POSE_4 或 POSE_0
|
|
|
|
+// // 转换位置坐标格式 (参考Python版本的targets格式)
|
|
|
|
+// if (location != null && location.size() >= 3) {
|
|
|
|
+// float[] targetPoint = {location.get(0)/100f, location.get(1)/100f, location.get(2)/100f};
|
|
|
|
+// result.setLocation(targetPoint);
|
|
|
|
+// }
|
|
|
|
+// result.setShouldProcess(true);
|
|
|
|
+// } else if ("LNA".equals(devType)) {
|
|
|
|
+// // LNA设备的处理逻辑 (参考Python版本)
|
|
|
|
+// if (realtimePose == null || realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
|
|
|
|
+// result.setShouldProcess(false);
|
|
|
|
+// return result;
|
|
|
|
+// }
|
|
|
|
+// result.setPose(realtimePose.get(0));
|
|
|
|
+// // 转换位置坐标格式
|
|
|
|
+// if (location != null && location.size() >= 3) {
|
|
|
|
+// float[] targetPoint = {location.get(0)/100f, location.get(1)/100f, location.get(2)/100f};
|
|
|
|
+// result.setLocation(targetPoint);
|
|
|
|
+// }
|
|
|
|
+// result.setShouldProcess(true);
|
|
|
|
+// } else {
|
|
|
|
+// result.setShouldProcess(false);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return result;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 放入点云数据到队列 (对应Python版本的put_cloud_points_que方法)
|
|
|
|
+// * @param cloudPoints 点云数据
|
|
|
|
+// */
|
|
|
|
+// public void putCloudPointsQueue(List<List<Float>> cloudPoints) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// if (cloudPoints != null && !cloudPoints.isEmpty()) {
|
|
|
|
+// // 如果队列已满,移除最老的数据
|
|
|
|
+// while (cloudPointsQueue.size() >= MAX_CLOUD_POINTS_QUEUE_SIZE) {
|
|
|
|
+// cloudPointsQueue.poll();
|
|
|
|
+// }
|
|
|
|
+// cloudPointsQueue.offer(new ArrayList<>(cloudPoints));
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取点云数据队列 (用于调试和分析)
|
|
|
|
+// * @return 点云数据队列的副本
|
|
|
|
+// */
|
|
|
|
+// public List<List<List<Float>>> getCloudPointsQueue() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return new ArrayList<>(cloudPointsQueue);
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 清空点云数据队列
|
|
|
|
+// */
|
|
|
|
+// public void clearCloudPointsQueue() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// cloudPointsQueue.clear();
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检查跌倒告警间隔 (对应Python版本的告警间隔检查逻辑)
|
|
|
|
+// * @param currentTime 当前时间
|
|
|
|
+// * @return true如果可以发送跌倒告警
|
|
|
|
+// */
|
|
|
|
+// public boolean checkFallAlarmInterval(Long currentTime) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// // 检查告警确认状态 (对应Python: device.get_alarm_ack())
|
|
|
|
+// if (Boolean.TRUE.equals(alarmAck)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 检查告警间隔 (对应Python: now - device.last_report_fall_time() < device.alarm_interval())
|
|
|
|
+// if (lastReportFallTime != null && currentTime != null) {
|
|
|
|
+// long timeSinceLastFall = currentTime - lastReportFallTime;
|
|
|
|
+// return timeSinceLastFall >= (alarmInterval != null ? alarmInterval : 30000L); // 默认30秒间隔
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return true; // 第一次跌倒或时间信息不完整时允许发送
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 设置调试参数集合 (对应应用层的setDebugParams需求)
|
|
|
|
+// * @param debugParams 调试参数集合
|
|
|
|
+// */
|
|
|
|
+// public void setDebugParams(Map<String, Object> debugParams) {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// if (debugParams != null) {
|
|
|
|
+// this.debugParams.clear();
|
|
|
|
+// this.debugParams.putAll(debugParams);
|
|
|
|
+// }
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取调试参数集合 (对应应用层的getDebugParams需求)
|
|
|
|
+// * @return 调试参数集合
|
|
|
|
+// */
|
|
|
|
+// public Map<String, Object> getDebugParams() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+// return new HashMap<>(debugParams); // 返回副本确保线程安全
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 停留时间记录
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// public static class StayTimeRecord {
|
|
|
|
+// private String devId;
|
|
|
|
+// private Long enterTime;
|
|
|
|
+// private Long leaveTime;
|
|
|
|
+// private Long stayTime;
|
|
|
|
+// private boolean needAlarm;
|
|
|
|
+// private String alarmType;
|
|
|
|
+// private String alarmDescription;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 跌倒事件处理结果
|
|
|
|
+// */
|
|
|
|
+// @Getter
|
|
|
|
+// @Setter
|
|
|
|
+// @NoArgsConstructor
|
|
|
|
+// @AllArgsConstructor
|
|
|
|
+// public static class FallEventResult {
|
|
|
|
+// private String devId;
|
|
|
|
+// private String event;
|
|
|
|
+// private Integer pose;
|
|
|
|
+// private Object location; // 修改为Object类型,匹配MqttGateway接口
|
|
|
|
+// private boolean shouldProcess;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 获取数据量最多的一组点云数据,然后清空cloud_points_que_
|
|
|
|
+// * (对应Python版本的get_max_len_cloud_points方法)
|
|
|
|
+// * @return 数据量最多的点云list,失败返回null
|
|
|
|
+// */
|
|
|
|
+// public List<List<Float>> getMaxLenCloudPoints() {
|
|
|
|
+// try {
|
|
|
|
+// lock.lock();
|
|
|
|
+//
|
|
|
|
+// // 对应Python: if self.dev_type_ == "LNB": return None
|
|
|
|
+// if ("LNB".equals(devType)) {
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 对应Python: 取出数据量最多的的点云,成功返回点云list,失败返回None
|
|
|
|
+// int maxLen = 0;
|
|
|
|
+// List<List<Float>> maxLenList = null;
|
|
|
|
+//
|
|
|
|
+// // 对应Python: while not self.cloud_points_que_.empty():
|
|
|
|
+// while (!cloudPointsQueue.isEmpty()) {
|
|
|
|
+// List<List<Float>> currentList = cloudPointsQueue.poll();
|
|
|
|
+// // 对应Python: if len(current_list) >= max_len:
|
|
|
|
+// if (currentList != null && currentList.size() >= maxLen) {
|
|
|
|
+// maxLen = currentList.size();
|
|
|
|
+// maxLenList = currentList;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return maxLenList;
|
|
|
|
+// } finally {
|
|
|
|
+// lock.unlock();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//}
|