diff --git a/src/main/java/com/techsor/datacenter/sender/dao/CsdjDao.java b/src/main/java/com/techsor/datacenter/sender/dao/CsdjDao.java index 8ccade2..6433531 100644 --- a/src/main/java/com/techsor/datacenter/sender/dao/CsdjDao.java +++ b/src/main/java/com/techsor/datacenter/sender/dao/CsdjDao.java @@ -24,6 +24,7 @@ public class CsdjDao { return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> { CsdjDeviceRealtime device = new CsdjDeviceRealtime(); device.setTerminalId(rs.getString("terminal_id")); + device.setDeviceId(rs.getString("device_id")); device.setCompanyId(rs.getLong("company_id")); // 基础信息 @@ -92,22 +93,23 @@ public class CsdjDao { } } - public void insertCsdjLog(String terminalId, String rawHex, Long createdAt, String parsedJson, String parsedContent) { - String sql = "INSERT INTO csdj_log (terminal_id, raw_hex, created_at, parsed_json, parsed_content) VALUES (?, ?, ?, ?, ?)"; - jdbcTemplate.update(sql, terminalId, rawHex, createdAt, parsedJson, parsedContent); + public void insertCsdjLog(String terminalId, String deviceId, String rawHex, Long createdAt, String parsedJson, String parsedContent) { + String sql = "INSERT INTO csdj_log (terminal_id, device_id, raw_hex, created_at, parsed_json, parsed_content) VALUES (?, ?, ?, ?, ?, ?)"; + jdbcTemplate.update(sql, terminalId, deviceId, rawHex, createdAt, parsedJson, parsedContent); } public void insertAlarm(CsdjAlarmHistory csdjAlarmHistory) { String sql = "INSERT IGNORE INTO csdj_alarm_history (" + - "company_id, raw_hex, terminal_id, terminal_no, " + + "company_id, raw_hex, device_id, terminal_id, terminal_no, " + "alarm_time, alarm_timestamp, recovery_time, recovery_timestamp, " + "alarm_state, state_raw, abnormal_mode, alert_history_id, " + "created_at, updated_at" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; jdbcTemplate.update(sql, csdjAlarmHistory.getCompanyId(), csdjAlarmHistory.getRawHex(), + csdjAlarmHistory.getDeviceId(), csdjAlarmHistory.getTerminalId(), csdjAlarmHistory.getTerminalNo(), @@ -135,8 +137,13 @@ public class CsdjDao { } public void saveOrUpdateDeviceRealtime(CsdjDeviceRealtime device) { + // deviceId 为 null 时设置为空字符串,防止唯一索引 (terminal_id, device_id) 出问题 + if (device.getDeviceId() == null) { + device.setDeviceId(""); + } + String sql = "INSERT INTO csdj_device_realtime (" + - "terminal_id, company_id, " + + "terminal_id, device_id, company_id, " + "last_notification_time, last_notification_timestamp, last_raw_hex, " + "digital_input_json, " + "di_1_no, di_1_is_alarm, di_1_state_raw, di_1_state_text, di_1_abnormal_mode, " + @@ -152,7 +159,7 @@ public class CsdjDao { "system_is_power_off, system_is_battery_low, system_is_line_disconnected, " + "system_is_slave_communication_error, system_state_raw, " + "created_at, updated_at" + - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " + "ON DUPLICATE KEY UPDATE " + "company_id = VALUES(company_id), " + "last_notification_time = VALUES(last_notification_time), " + @@ -175,6 +182,7 @@ public class CsdjDao { jdbcTemplate.update(sql, device.getTerminalId(), + device.getDeviceId(), device.getCompanyId(), device.getLastNotificationTime() != null diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAlarmHistory.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAlarmHistory.java index b7f1054..78c395f 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAlarmHistory.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAlarmHistory.java @@ -31,6 +31,11 @@ public class CsdjAlarmHistory { */ private String rawHex; + /** + * 设备ID(如 031-D04) + */ + private String deviceId; + /** * 终端ID */ diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAnalogInputTerminal.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAnalogInputTerminal.java index 0dce71c..3f083e4 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAnalogInputTerminal.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjAnalogInputTerminal.java @@ -20,4 +20,5 @@ public class CsdjAnalogInputTerminal { private Integer thresholdNo; // 阈值编号 private Long additionalData; // 附加数据(模拟值/累计值) private String stateText; // 状态文本 + private String deviceId; // 设备ID(如 031-A01) } diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDeviceRealtime.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDeviceRealtime.java index e318e2a..c1c9936 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDeviceRealtime.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDeviceRealtime.java @@ -18,6 +18,7 @@ import java.time.LocalDateTime; public class CsdjDeviceRealtime { private Long id; private String terminalId; + private String deviceId; private Long companyId; // ===== 通報基础信息 ===== diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalInputTerminal.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalInputTerminal.java index e3d28da..4e3fe36 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalInputTerminal.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalInputTerminal.java @@ -43,4 +43,9 @@ public class CsdjDigitalInputTerminal { * 端子状态文本说明 */ private String stateText; + + /** + * 设备ID(如 031-D04) + */ + private String deviceId; } diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalOutputTerminal.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalOutputTerminal.java index c54a174..95fd5f5 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalOutputTerminal.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjDigitalOutputTerminal.java @@ -18,4 +18,5 @@ public class CsdjDigitalOutputTerminal { private Integer stateRaw; // 端子状态原始值 private String outputState; // 输出接点状态(OFF/ON) private Long additionalData; // 附加数据 + private String deviceId; // 设备ID(如 031-D01) } diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjSystemState.java b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjSystemState.java index c787ec8..69db66e 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjSystemState.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/csdj/CsdjSystemState.java @@ -22,4 +22,5 @@ public class CsdjSystemState { private Boolean isLineDisconnected; // 线路状态(0=正常,1=断开) private Boolean isSlaveCommunicationError; // 子机通信状态 private Integer stateRaw; // 原始状态值 + private String deviceId; // 设备ID(如 031-S01) } diff --git a/src/main/java/com/techsor/datacenter/sender/service/CsdjService.java b/src/main/java/com/techsor/datacenter/sender/service/CsdjService.java index 9a2f559..7e47521 100644 --- a/src/main/java/com/techsor/datacenter/sender/service/CsdjService.java +++ b/src/main/java/com/techsor/datacenter/sender/service/CsdjService.java @@ -70,7 +70,7 @@ public class CsdjService { if (notificationData == null) { log.warn("[CSDJ] 解析通報数据失败,terminalId:{}", csdjEntity.getTerminalId()); // 即使解析失败,也先存入原始数据 - csdjDao.insertCsdjLog(terminalId, csdjEntity.getData(), csdjEntity.getTs(), null, null); + csdjDao.insertCsdjLog(terminalId, terminalId, csdjEntity.getData(), csdjEntity.getTs(), null, null); return; } @@ -78,6 +78,9 @@ public class CsdjService { Integer.toHexString(notificationData.getNotificationType() & 0xFF).toUpperCase(), notificationData.getNotificationTime()); + // 给所有端子设置 deviceId(格式:terminalId-D04 / terminalId-A01 / terminalId-S01) + setDeviceIds(terminalId, notificationData); + // 调试信息 log.info("[CSDJ] デジタル入力端子列表: {}", notificationData.getDigitalInputTerminals()); log.info("[CSDJ] デジタル入力端子数量: {}", @@ -89,7 +92,8 @@ public class CsdjService { String parsedContent = buildParsedContent(notificationData); // 3. 存入 csdj_log 表 - csdjDao.insertCsdjLog(terminalId, csdjEntity.getData(), csdjEntity.getTs(), parsedJson, parsedContent); + String logDeviceId = collectDeviceIds(notificationData); + csdjDao.insertCsdjLog(terminalId, logDeviceId, csdjEntity.getData(), csdjEntity.getTs(), parsedJson, parsedContent); // 4. 处理デジタル入力端子(告警/恢复) List digitalTerminals = notificationData.getDigitalInputTerminals(); @@ -112,17 +116,19 @@ public class CsdjService { private void processDigitalTerminal(CsdjEntity csdjEntity, CsdjNotificationData notificationData, CsdjDigitalInputTerminal terminal, DeviceEntity deviceEntity) { String terminalId = csdjEntity.getTerminalId(); + String deviceId = terminal.getDeviceId(); Integer terminalNo = terminal.getTerminalNo(); Boolean isAlarm = terminal.getIsAlarm(); String stateText = terminal.getStateText(); - log.info("[CSDJ] デジタル入力端子,terminalId:{}, No:{}, state:{}, isAlarm:{}", - terminalId, terminalNo, stateText, isAlarm); + log.info("[CSDJ] デジタル入力端子,terminalId:{}, deviceId:{}, No:{}, state:{}, isAlarm:{}", + terminalId, deviceId, terminalNo, stateText, isAlarm); Long companyId = deviceEntity.getCompanyId(); CsdjAlarmHistory csdjAlarmHistory = new CsdjAlarmHistory(); csdjAlarmHistory.setCompanyId(companyId); + csdjAlarmHistory.setDeviceId(deviceId); csdjAlarmHistory.setTerminalId(terminalId); csdjAlarmHistory.setTerminalNo(terminalNo); csdjAlarmHistory.setStateRaw(terminal.getStateRaw()); @@ -132,13 +138,13 @@ public class CsdjService { csdjAlarmHistory.setRawHex(rawHex); DeviceInfoVO deviceInfoVO = new DeviceInfoVO(); - deviceInfoVO.setDeviceId(deviceEntity.getDeviceId()); + deviceInfoVO.setDeviceId(deviceId); deviceInfoVO.setBuildingId(deviceEntity.getBuildingId()); deviceInfoVO.setBigClassId(deviceEntity.getBigClassId()); deviceInfoVO.setCategoryId(deviceEntity.getCategoryId()); DynamodbEntity entity = new DynamodbEntity(); - entity.setDeviceId(terminalId); + entity.setDeviceId(terminal.getDeviceId()); entity.setRetainAlert(deviceEntity.getRetainAlert()); if (isAlarm) { @@ -155,8 +161,8 @@ public class CsdjService { csdjAlarmHistory.setRecoveryTime(null); csdjAlarmHistory.setRecoveryTimestamp(null); - log.info("[CSDJ] 发生告警!terminalId:{}, terminalNo:{}, state:{}", - terminalId, terminalNo, stateText); + log.info("[CSDJ] 发生告警!terminalId:{}, deviceId:{}, terminalNo:{}, state:{}", + terminalId, deviceId, terminalNo, stateText); } else { dashboardAlertDao.updateLatestAlertToAutoRecovered(entity); @@ -164,13 +170,74 @@ public class CsdjService { csdjAlarmHistory.setRecoveryTime(notificationData.getNotificationTime()); csdjAlarmHistory.setRecoveryTimestamp(notificationData.getJapanTimestamp()); - log.info("[CSDJ] 告警恢复!terminalId:{}, terminalNo:{}, state:{}", - terminalId, terminalNo, stateText); + log.info("[CSDJ] 告警恢复!terminalId:{}, deviceId:{}, terminalNo:{}, state:{}", + terminalId, deviceId, terminalNo, stateText); } csdjDao.insertAlarm(csdjAlarmHistory); } + /** + * 给所有端子设置 deviceId + * 格式:terminalId-前缀+端子号(如 031-D04, 031-A01, 031-S01) + */ + private void setDeviceIds(String terminalId, CsdjNotificationData data) { + // デジタル入力端子 → D 前缀 + if (data.getDigitalInputTerminals() != null) { + for (CsdjDigitalInputTerminal t : data.getDigitalInputTerminals()) { + t.setDeviceId(terminalId + "-D" + String.format("%02d", t.getTerminalNo())); + } + } + // アナログ入力端子 → A 前缀 + if (data.getAnalogInputTerminals() != null) { + for (CsdjAnalogInputTerminal t : data.getAnalogInputTerminals()) { + t.setDeviceId(terminalId + "-A" + String.format("%02d", t.getTerminalNo())); + } + } + // デジタル出力端子 → D 前缀 + if (data.getDigitalOutputTerminals() != null) { + for (CsdjDigitalOutputTerminal t : data.getDigitalOutputTerminals()) { + t.setDeviceId(terminalId + "-D" + String.format("%02d", t.getTerminalNo())); + } + } + // システム状態 → S 前缀(用 stateNo) + CsdjSystemState systemState = data.getSystemState(); + if (systemState != null && systemState.getStateNo() != null) { + systemState.setDeviceId(terminalId + "-S" + String.format("%02d", systemState.getStateNo())); + } + } + + /** + * 收集通報数据中所有端子的 deviceId,用逗号拼接 + */ + private String collectDeviceIds(CsdjNotificationData data) { + StringBuilder sb = new StringBuilder(); + if (data.getDigitalInputTerminals() != null) { + for (CsdjDigitalInputTerminal t : data.getDigitalInputTerminals()) { + if (sb.length() > 0) sb.append(","); + sb.append(t.getDeviceId()); + } + } + if (data.getAnalogInputTerminals() != null) { + for (CsdjAnalogInputTerminal t : data.getAnalogInputTerminals()) { + if (sb.length() > 0) sb.append(","); + sb.append(t.getDeviceId()); + } + } + if (data.getDigitalOutputTerminals() != null) { + for (CsdjDigitalOutputTerminal t : data.getDigitalOutputTerminals()) { + if (sb.length() > 0) sb.append(","); + sb.append(t.getDeviceId()); + } + } + CsdjSystemState systemState = data.getSystemState(); + if (systemState != null && systemState.getDeviceId() != null) { + if (sb.length() > 0) sb.append(","); + sb.append(systemState.getDeviceId()); + } + return sb.toString(); + } + private void saveDeviceRealtime(String terminalId, Long companyId, String rawHex, CsdjNotificationData data) { try { @@ -181,6 +248,7 @@ public class CsdjService { deviceRealtime = new CsdjDeviceRealtime(); deviceRealtime.setTerminalId(terminalId); } + deviceRealtime.setDeviceId(terminalId); deviceRealtime.setCompanyId(companyId); deviceRealtime.setLastNotificationTime(data.getNotificationTime()); deviceRealtime.setLastNotificationTimestamp(data.getJapanTimestamp());