package com.ruoyi.tcp; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.device.srgv.domain.DeviceSrgv; import com.ruoyi.device.ssj.domain.DeviceSsj; import com.ruoyi.device.tsj.domain.DeviceTsj; import com.ruoyi.schedule.plcRead.srgv.PlcSrgvRead; import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead; import com.ruoyi.schedule.plcRead.tsj.PlcTsjRead; import lombok.Data; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; @Component public class GetDeviceAlarm { private final TcpServerManager manager; private final ObjectMapper objectMapper = new ObjectMapper(); /** * 构造函数:注入 TCP 管理器,用于管理 5555 端口客户端与广播 */ public GetDeviceAlarm(TcpServerManager manager) { this.manager = manager; } /** * 初始化:注册 5555 端口的客户端连接监听,客户端第一次连接时立即发送报警数据 */ @PostConstruct public void init() { manager.setClientListener("port5555", this::handleConnect); } /** * 客户端连接处理:构建报警数据并写入到 Socket 输出流 */ private void handleConnect(Socket socket) { try { String payload = buildAlarmPayload(); OutputStream os = socket.getOutputStream(); os.write(((payload == null ? "" : payload) + "\n").getBytes(StandardCharsets.UTF_8)); os.flush(); } catch (Exception ignored) { } } /** * 周期发送:每 2 秒检查 5555 端口是否有连接,有则广播报警数据,无连接不发送 */ @Scheduled(fixedRate = 2000) public void send() { Integer count = manager.status().getOrDefault("port5555", 0); if (count != null && count > 0) { String payload = buildAlarmPayload(); manager.broadcast("port5555", payload == null ? "" : payload); } } /** * 构建报警数据:汇总四向车、输送机、提升机报警 * - 四向车:报警代码 > 1,字典类型 srgv_alarm * - 输送机:报警代码 > 2,字典类型 ssj_ex * - 提升机:报警代码 > 100,字典类型 tsj_alarm * 返回 JSON 字符串格式:{"alarm":[{id,name,alarm,alarmMsg}]} */ private String buildAlarmPayload() { List alarms = new ArrayList<>(); Map srgvMap = PlcSrgvRead.deviceSrgvMap; if (srgvMap != null) { for (DeviceSrgv d : srgvMap.values()) { Integer code = d.getAlarm(); if (code != null && code > 1) { AlarmDto dto = new AlarmDto(); dto.setId(d.getDeviceId() == null ? "" : String.valueOf(d.getDeviceId())); dto.setName("四向车"); dto.setAlarm(code == null ? "" : String.valueOf(code)); dto.setAlarmMsg(DictUtils.getDictLabel("srgv_alarm", code == null ? "" : String.valueOf(code))); alarms.add(dto); } } } Map ssjMap = PlcSsjRead.deviceSsjMap; if (ssjMap != null) { for (DeviceSsj d : ssjMap.values()) { Integer code = d.getException(); if (code != null && code > 2) { AlarmDto dto = new AlarmDto(); dto.setId(d.getDeviceCode() == null ? "" : d.getDeviceCode()); dto.setName("输送机"); dto.setAlarm(String.valueOf(code)); dto.setAlarmMsg(DictUtils.getDictLabel("ssj_ex", String.valueOf(code))); alarms.add(dto); } } } Map tsjMap = PlcTsjRead.deviceTsjMap; if (tsjMap != null) { for (Map.Entry entry : tsjMap.entrySet()) { String codeId = entry.getKey(); DeviceTsj d = entry.getValue(); Integer code = d.getSbzt(); if (code != null && code > 100) { AlarmDto dto = new AlarmDto(); dto.setId(codeId == null ? "" : codeId); dto.setName("提升机"); dto.setAlarm(String.valueOf(code)); dto.setAlarmMsg(DictUtils.getDictLabel("tsj_alarm", String.valueOf(code))); alarms.add(dto); } } } try { Wrapper w = new Wrapper(); w.setAlarm(alarms); return objectMapper.writeValueAsString(w); } catch (Exception e) { return "{\"alarm\":[]}"; } } @Data private static class Wrapper { private List alarm; } @Data private static class AlarmDto { private String id; private String name; private String alarm; private String alarmMsg; } }