From 11fae3d85c039c405a8d4c84409a488cb14a8f68 Mon Sep 17 00:00:00 2001 From: mh Date: Tue, 19 Mar 2024 17:06:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=88=90=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F+=E7=AD=96=E7=95=A5=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E6=95=B0=E6=8D=AE=E9=87=87=E9=9B=86=E5=8F=91?= =?UTF-8?q?=E9=80=81=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mh/user/constants/DeviceEnum.java | 59 ++ .../mh/user/constants/DeviceStrategyEnum.java | 59 ++ .../main/java/com/mh/user/factory/Device.java | 20 + .../com/mh/user/factory/DeviceFactory.java | 20 + .../java/com/mh/user/factory/EleMeter.java | 46 ++ .../java/com/mh/user/factory/HeatPump.java | 43 ++ .../com/mh/user/factory/HeatPumpStatus.java | 43 ++ .../com/mh/user/factory/PressureTrans.java | 43 ++ .../java/com/mh/user/factory/StatusCheck.java | 47 ++ .../java/com/mh/user/factory/TempControl.java | 43 ++ .../java/com/mh/user/factory/TempTrans.java | 43 ++ .../java/com/mh/user/factory/TimeControl.java | 43 ++ .../com/mh/user/factory/WaterLevelSwitch.java | 43 ++ .../java/com/mh/user/factory/WtMeter.java | 47 ++ .../user/serialport/SendAndReceiveByCom.java | 218 +++++++ .../serialport/SerialPortSendReceive.java | 281 --------- .../serialport/SerialPortSendReceive2.java | 54 -- .../mh/user/serialport/SerialPortSingle2.java | 201 +++---- .../mh/user/serialport/SerialPortThread.java | 6 +- .../com/mh/user/strategy/DeviceStrategy.java | 20 + .../user/strategy/DeviceStrategyFactory.java | 18 + .../mh/user/strategy/EleMeterStrategy.java | 119 ++++ .../user/strategy/HeatPumpStatusStrategy.java | 241 ++++++++ .../mh/user/strategy/HeatPumpStrategy.java | 398 +++++++++++++ .../user/strategy/PressureTransStrategy.java | 110 ++++ .../mh/user/strategy/StatusCheckStrategy.java | 126 +++++ .../mh/user/strategy/TempControlStrategy.java | 129 +++++ .../mh/user/strategy/TempTransStrategy.java | 120 ++++ .../mh/user/strategy/TimeControlStrategy.java | 120 ++++ .../strategy/WaterLevelSwitchStrategy.java | 531 ++++++++++++++++++ .../com/mh/user/strategy/WtMeterStrategy.java | 133 +++++ 31 files changed, 2991 insertions(+), 433 deletions(-) create mode 100644 user-service/src/main/java/com/mh/user/constants/DeviceEnum.java create mode 100644 user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java create mode 100644 user-service/src/main/java/com/mh/user/factory/Device.java create mode 100644 user-service/src/main/java/com/mh/user/factory/DeviceFactory.java create mode 100644 user-service/src/main/java/com/mh/user/factory/EleMeter.java create mode 100644 user-service/src/main/java/com/mh/user/factory/HeatPump.java create mode 100644 user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java create mode 100644 user-service/src/main/java/com/mh/user/factory/PressureTrans.java create mode 100644 user-service/src/main/java/com/mh/user/factory/StatusCheck.java create mode 100644 user-service/src/main/java/com/mh/user/factory/TempControl.java create mode 100644 user-service/src/main/java/com/mh/user/factory/TempTrans.java create mode 100644 user-service/src/main/java/com/mh/user/factory/TimeControl.java create mode 100644 user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java create mode 100644 user-service/src/main/java/com/mh/user/factory/WtMeter.java create mode 100644 user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java delete mode 100644 user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/DeviceStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/DeviceStrategyFactory.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/HeatPumpStatusStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/HeatPumpStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/PressureTransStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/StatusCheckStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/TempControlStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/TempTransStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/TimeControlStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/WaterLevelSwitchStrategy.java create mode 100644 user-service/src/main/java/com/mh/user/strategy/WtMeterStrategy.java diff --git a/user-service/src/main/java/com/mh/user/constants/DeviceEnum.java b/user-service/src/main/java/com/mh/user/constants/DeviceEnum.java new file mode 100644 index 0000000..a37241b --- /dev/null +++ b/user-service/src/main/java/com/mh/user/constants/DeviceEnum.java @@ -0,0 +1,59 @@ +package com.mh.user.constants; + +import com.mh.user.factory.*; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 设备枚举类 + * @date 2024-03-19 10:06:29 + */ +public enum DeviceEnum { + + WtMeterEnum("水表", WtMeter.getInstance()), + EleMeterEnum("电表", EleMeter.getInstance()), + PressureTransEnum("压变", PressureTrans.getInstance()), + HeatPumpEnum("热泵", HeatPump.getInstance()), + TempControlEnum("温控", TempControl.getInstance()), + TimeControlEnum("时控", TimeControl.getInstance()), + WaterLevelSwitchEnum("水位开关", WaterLevelSwitch.getInstance()), + StatusCheckEnum("状态检测", StatusCheck.getInstance()), + TempTransEnum("温度变送器", TempTrans.getInstance()), + HeatPumpStatusEnum("热泵状态", HeatPumpStatus.getInstance()); + + private String deviceType; + + private Device device; + + private + DeviceEnum(String deviceType, Device device) { + this.deviceType = deviceType; + this.device = device; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + + public static Device getDevice(String deviceType) { + for (DeviceEnum deviceEnum : DeviceEnum.values()) { + if (deviceEnum.getDeviceType().equals(deviceType)) { + return deviceEnum.getDevice(); + } + } + return null; + } +} diff --git a/user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java b/user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java new file mode 100644 index 0000000..9fe6db5 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java @@ -0,0 +1,59 @@ +package com.mh.user.constants; + +import com.mh.user.factory.*; +import com.mh.user.strategy.*; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 设备枚举类 + * @date 2024-03-19 10:06:29 + */ +public enum DeviceStrategyEnum { + + WtMeterEnum("水表", WtMeterStrategy.getInstance()), + EleMeterEnum("电表", EleMeterStrategy.getInstance()), + PressureTransEnum("压变", PressureTransStrategy.getInstance()), + HeatPumpEnum("热泵", HeatPumpStrategy.getInstance()), + TempControlEnum("温控", TempControlStrategy.getInstance()), + TimeControlEnum("时控", TimeControlStrategy.getInstance()), + WaterLevelSwitchEnum("水位开关", WaterLevelSwitchStrategy.getInstance()), + StatusCheckEnum("状态检测", StatusCheckStrategy.getInstance()), + TempTransEnum("温度变送器", TempTransStrategy.getInstance()), + HeatPumpStatusEnum("热泵状态", HeatPumpStatusStrategy.getInstance()); + + private String deviceType; + + private DeviceStrategy deviceStrategy; + + private DeviceStrategyEnum(String deviceType, DeviceStrategy deviceStrategy) { + this.deviceType = deviceType; + this.deviceStrategy = deviceStrategy; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public DeviceStrategy getDeviceStrategy() { + return deviceStrategy; + } + + public void setDeviceStrategy(DeviceStrategy deviceStrategy) { + this.deviceStrategy = deviceStrategy; + } + + public static DeviceStrategy getDeviceStrategy(String deviceType) { + for (DeviceStrategyEnum deviceEnum : DeviceStrategyEnum.values()) { + if (deviceEnum.getDeviceType().equals(deviceType)) { + return deviceEnum.getDeviceStrategy(); + } + } + return null; + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/Device.java b/user-service/src/main/java/com/mh/user/factory/Device.java new file mode 100644 index 0000000..5867897 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/Device.java @@ -0,0 +1,20 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 设备接口 + * @date 2024-03-15 16:48:26 + */ +public interface Device { + + void setStrategy(DeviceStrategy strategy); + + String createOrders(DeviceCodeParamEntity deviceCodeParamEntity); + + String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr); +} diff --git a/user-service/src/main/java/com/mh/user/factory/DeviceFactory.java b/user-service/src/main/java/com/mh/user/factory/DeviceFactory.java new file mode 100644 index 0000000..08a9cc2 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/DeviceFactory.java @@ -0,0 +1,20 @@ +package com.mh.user.factory; + +import com.mh.user.constants.DeviceEnum; +import lombok.extern.slf4j.Slf4j; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 设备工厂类 + * @date 2024-03-15 17:09:49 + */ +@Slf4j +public class DeviceFactory { + + public static Device createDevice(String deviceType) { + return DeviceEnum.getDevice(deviceType); + } + +} diff --git a/user-service/src/main/java/com/mh/user/factory/EleMeter.java b/user-service/src/main/java/com/mh/user/factory/EleMeter.java new file mode 100644 index 0000000..48e1774 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/EleMeter.java @@ -0,0 +1,46 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; +import lombok.extern.slf4j.Slf4j; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 电表设备 + * @date 2024-03-15 16:52:39 + */ +@Slf4j +public class EleMeter implements Device { + + private DeviceStrategy eleMeterStrategy; + + private static class SingletonHolder { + private static final EleMeter INSTANCE = new EleMeter(); + } + + private EleMeter() { + // 防止外部直接实例化 + } + + public static EleMeter getInstance() { + return EleMeter.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.eleMeterStrategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + log.info("电表设备创建报文"); + return eleMeterStrategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return eleMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/HeatPump.java b/user-service/src/main/java/com/mh/user/factory/HeatPump.java new file mode 100644 index 0000000..7382dbe --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/HeatPump.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 热泵 + * @date 2024-03-18 16:53:35 + */ +public class HeatPump implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final HeatPump INSTANCE = new HeatPump(); + } + + private HeatPump() { + // 防止外部直接实例化 + } + + public static HeatPump getInstance() { + return HeatPump.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java b/user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java new file mode 100644 index 0000000..042c0da --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 热泵状态 + * @date 2024-03-18 16:53:35 + */ +public class HeatPumpStatus implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final HeatPumpStatus INSTANCE = new HeatPumpStatus(); + } + + private HeatPumpStatus() { + // 防止外部直接实例化 + } + + public static HeatPumpStatus getInstance() { + return HeatPumpStatus.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/PressureTrans.java b/user-service/src/main/java/com/mh/user/factory/PressureTrans.java new file mode 100644 index 0000000..712d7d6 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/PressureTrans.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 压力变送器 + * @date 2024-03-18 16:53:35 + */ +public class PressureTrans implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final PressureTrans INSTANCE = new PressureTrans(); + } + + private PressureTrans() { + // 防止外部直接实例化 + } + + public static PressureTrans getInstance() { + return PressureTrans.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/StatusCheck.java b/user-service/src/main/java/com/mh/user/factory/StatusCheck.java new file mode 100644 index 0000000..ef90b99 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/StatusCheck.java @@ -0,0 +1,47 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; +import lombok.extern.slf4j.Slf4j; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 状态检测 + * @date 2024-03-15 17:07:54 + */ +@Slf4j +public class StatusCheck implements Device { + + private DeviceStrategy wtMeterStrategy; + + private static class SingletonHolder { + private static final StatusCheck INSTANCE = new StatusCheck(); + } + + private StatusCheck() { + // 防止外部直接实例化 + } + + public static StatusCheck getInstance() { + return SingletonHolder.INSTANCE; + } + + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.wtMeterStrategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + log.info("水表设备创建报文"); + return wtMeterStrategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return wtMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/TempControl.java b/user-service/src/main/java/com/mh/user/factory/TempControl.java new file mode 100644 index 0000000..1795c6a --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/TempControl.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 温度控制器 + * @date 2024-03-18 16:53:35 + */ +public class TempControl implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final TempControl INSTANCE = new TempControl(); + } + + private TempControl() { + // 防止外部直接实例化 + } + + public static TempControl getInstance() { + return TempControl.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/TempTrans.java b/user-service/src/main/java/com/mh/user/factory/TempTrans.java new file mode 100644 index 0000000..d7362a2 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/TempTrans.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 压力变送器 + * @date 2024-03-18 16:53:35 + */ +public class TempTrans implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final TempTrans INSTANCE = new TempTrans(); + } + + private TempTrans() { + // 防止外部直接实例化 + } + + public static TempTrans getInstance() { + return TempTrans.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/TimeControl.java b/user-service/src/main/java/com/mh/user/factory/TimeControl.java new file mode 100644 index 0000000..afd887c --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/TimeControl.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 时间控制器 + * @date 2024-03-18 16:53:35 + */ +public class TimeControl implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final TimeControl INSTANCE = new TimeControl(); + } + + private TimeControl() { + // 防止外部直接实例化 + } + + public static TimeControl getInstance() { + return TimeControl.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java b/user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java new file mode 100644 index 0000000..1642677 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java @@ -0,0 +1,43 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 水位开关控制 + * @date 2024-03-18 16:53:35 + */ +public class WaterLevelSwitch implements Device { + + private DeviceStrategy strategy; + + private static class SingletonHolder { + private static final WaterLevelSwitch INSTANCE = new WaterLevelSwitch(); + } + + private WaterLevelSwitch() { + // 防止外部直接实例化 + } + + public static WaterLevelSwitch getInstance() { + return WaterLevelSwitch.SingletonHolder.INSTANCE; + } + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.strategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + return strategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/factory/WtMeter.java b/user-service/src/main/java/com/mh/user/factory/WtMeter.java new file mode 100644 index 0000000..0293781 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/factory/WtMeter.java @@ -0,0 +1,47 @@ +package com.mh.user.factory; + +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.strategy.DeviceStrategy; +import lombok.extern.slf4j.Slf4j; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 水表设备 + * @date 2024-03-15 17:07:54 + */ +@Slf4j +public class WtMeter implements Device { + + private DeviceStrategy wtMeterStrategy; + + private static class SingletonHolder { + private static final WtMeter INSTANCE = new WtMeter(); + } + + private WtMeter() { + // 防止外部直接实例化 + } + + public static WtMeter getInstance() { + return SingletonHolder.INSTANCE; + } + + + @Override + public void setStrategy(DeviceStrategy strategy) { + this.wtMeterStrategy = strategy; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + log.info("水表设备创建报文"); + return wtMeterStrategy.createOrders(deviceCodeParamEntity); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + return wtMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + } +} diff --git a/user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java b/user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java new file mode 100644 index 0000000..5da937b --- /dev/null +++ b/user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java @@ -0,0 +1,218 @@ +package com.mh.user.serialport; + +import com.mh.common.utils.StringUtils; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.factory.Device; +import com.mh.user.factory.DeviceFactory; +import com.mh.user.service.BuildingService; +import com.mh.user.service.DeviceInstallService; +import com.mh.user.service.NowDataService; +import com.mh.user.service.SysParamService; +import com.mh.user.strategy.DeviceStrategy; +import com.mh.user.strategy.DeviceStrategyFactory; +import com.mh.user.utils.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import purejavacomm.SerialPort; + +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 通过串口发送和接收数据 + * @date 2024-03-18 14:56:32 + */ +@Slf4j +public class SendAndReceiveByCom { + + List deviceManageEntityList; + + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class); + NowDataService nowDataService = context.getBean(NowDataService.class); + BuildingService buildingService = context.getBean(BuildingService.class); + AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); + + SysParamService sysParamService = context.getBean(SysParamService.class); + + public void sendAndReceive(String sort, String thread) { + SerialPort serialPort = null; + CacheUtil cacheUtil = CacheUtil.getInstance(); + try { + //生成对应的采集指令 + List deviceParamsByType = cacheUtil.getDeviceParamsByType(sort); + deviceManageEntityList = deviceParamsByType + .parallelStream() + .filter(value -> value.getThread().equals(thread)) + .sorted(Comparator.comparing(DeviceCodeParamEntity::getDataCom)) + .collect(Collectors.toList()); + int size = deviceManageEntityList.size(); + for (int i = 0; i < size; i++) { + //判断网页端是否有操作设备的 + if (Constant.WEB_FLAG) { + if (serialPort != null) { + SerialTool.closePort(serialPort); + } + log.info("有指令下发退出定时采集"); + break; + } + String comName = deviceManageEntityList.get(i).getDataCom(); + if (StringUtils.isBlank(comName)) { + log.info("-------------串口:" + comName + "不存在!-------------"); + continue; + } + + //获取设备实际波特率 + int baudrate = deviceManageEntityList.get(i).getBaudrate(); + //获取设备实际校验位 + String parity = deviceManageEntityList.get(i).getParity(); + String deviceAddr = deviceManageEntityList.get(i).getDeviceAddr(); + String deviceType = deviceManageEntityList.get(i).getDeviceType(); + String registerAddr = deviceManageEntityList.get(i).getRegisterAddr(); + String brand = deviceManageEntityList.get(i).getBrand();//品牌 + String buildingId = deviceManageEntityList.get(i).getBuildingId(); + String buildingName = buildingService.queryBuildingName(buildingId); //查询楼栋名称 + // 创建设备报文 + Device device = DeviceFactory.createDevice(deviceType); + DeviceStrategy strategy = DeviceStrategyFactory.createStrategy(deviceType); + if (null == strategy) { + continue; + } + device.setStrategy(strategy); + String sendStr = device.createOrders(deviceManageEntityList.get(i)); + + try { + //传入对应的串口参数并打开串口 + if (StringUtils.isBlank(parity) || parity.equalsIgnoreCase("none")) { + serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); + } else { + serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN); + } + if (null == serialPort) { + continue; + } + //向串口发送指令 + if (StringUtils.isBlank(sendStr)) { + continue; + } + SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType); + if (deviceType.equals("热泵")) { + for (int j = 0; j < 4; j++) { + Thread.sleep(1000); + // 判断网页端是否有操作设备的 + if (Constant.WEB_FLAG) { + SerialTool.closePort(serialPort); + log.info("有指令下发退出定时采集"); + break; + } + } + } else { + Thread.sleep(2000); + } + + //从串口读取数据 + byte[] bytes = SerialTool.readFromPort(serialPort); + Date date1 = new Date(); + String dateStr = DateUtil.dateToString(date1, "yyyy-MM-dd HH:mm:ss"); + if (bytes == null) { + SerialTool.closePort(serialPort); + log.info("串口" + serialPort.getName() + "没有数据返回!" + i); + log.info("----------------" + deviceType + "离线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName + "----------------"); + String time1 = deviceInstallService.selectLastDate(deviceType, deviceAddr, buildingId); + if (time1 == null) { + time1 = dateStr; + } + int d = ExchangeStringUtil.compareCopyTime(time1, dateStr); + if (d == 1) { + deviceInstallService.updateNotOnline(deviceAddr, deviceType, buildingId, "离线"); //所有设备离线 + if (deviceType.equals("热泵")) { + nowDataService.updateRunState(buildingId, deviceAddr, "离线", buildingName); //监控界面状态表热泵在线状态 + } + } + continue; + } + // 处理返回来的数据报文 + dealReceiveData(dateStr, serialPort, i, deviceAddr, deviceType, registerAddr, brand, buildingId, buildingName, bytes, device); + + } catch (Exception e) { + if (null != serialPort) { + SerialTool.closePort(serialPort); + log.error("发送窗口数据异常==>", e); + } + } finally { + if (null != serialPort) { + SerialTool.closePort(serialPort); + log.info("关闭串口==" + serialPort.getName()); + } + } + } + } catch (Exception e) { + log.error("-------------串口采集异常!----------->>", e); + } + } + + /** + * 处理返回来的数据 + * + * @param dateStr + * @param serialPort + * @param i + * @param deviceAddr + * @param deviceType + * @param registerAddr + * @param brand + * @param buildingId + * @param buildingName + * @param bytes + * @throws InterruptedException + */ + private void dealReceiveData(String dateStr, + SerialPort serialPort, + int i, + String deviceAddr, + String deviceType, + String registerAddr, + String brand, + String buildingId, + String buildingName, byte[] bytes, Device device) { + try { + String receiveStr = ""; + receiveStr = ExchangeStringUtil.parseByte2HexStr(bytes); + //去掉空格和null + receiveStr = receiveStr.replace("null", ""); + receiveStr = receiveStr.replace(" ", ""); + log.info("串口" + serialPort + "接受第" + i + "数据:" + receiveStr + ",大小: " + receiveStr.length()); + //返回值全部变成大写 + String receiveData = receiveStr.toUpperCase(); + //截取去掉FE + String dataStr; + if (receiveData.length() > 8) { + String str1 = receiveData.substring(0, 8); + String str2 = receiveData.substring(8); + dataStr = str1.replace("FE", "") + str2; + } else { + dataStr = receiveData.replace("FE", ""); + } + deviceInstallService.updateOnline(deviceAddr, deviceType, buildingId, "在线"); //设备在线 + log.info("----------------" + deviceType + "在线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName + "----------------"); + if (deviceType.equals("热泵")) { + String strState = nowDataService.selectState(buildingId, deviceAddr); + if (strState != null && strState.equals("离线")) { //采集到数据 + nowDataService.updateRunState(buildingId, deviceAddr, "不运行", buildingName); //监控界面状态表热泵在线状态 + } + } + // 解析返回来的数据 + device.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr); + + } catch (Exception e) { + log.error("楼栋:" + buildingName + "设备类型:" + deviceType + "保存数据库失败!" + i, e); + } + } + +} diff --git a/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java b/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java deleted file mode 100644 index 8032496..0000000 --- a/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java +++ /dev/null @@ -1,281 +0,0 @@ -//package com.mh.user.serialport; -// -//import com.mh.user.constants.Constant; -//import com.mh.user.entity.DeviceCodeParamEntity; -//import com.mh.user.service.BuildingService; -//import com.mh.user.service.DeviceCodeParamService; -//import com.mh.user.service.DeviceInstallService; -//import com.mh.user.service.NowDataService; -//import com.mh.user.utils.*; -//import lombok.extern.slf4j.Slf4j; -//import org.springframework.context.ApplicationContext; -//import gnu.io.SerialPort; -//import java.nio.ByteBuffer; -//import java.nio.charset.StandardCharsets; -//import java.text.SimpleDateFormat; -//import java.util.ArrayList; -//import java.util.Date; -//import java.util.List; -// -///** -// * @author nxr -// * @title : -// * @description : 串口发送和接收处理,采集类 -// * @updateTime 2022-08-10 -// * @throws : -// */ -//@Slf4j -//public class SerialPortSendReceive { -// -// private String receiveStr = null; -// public SerialPort serialPort = null; -// private int size = 0; -// private int baudrate=9600; -// private String parity=null; -// List deviceManageEntityList; -// // 调用service -// ApplicationContext context = SpringBeanUtil.getApplicationContext(); -// DeviceCodeParamService deviceCodeParamService = context.getBean(DeviceCodeParamService.class); -// DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class); -// NowDataService nowDataService = context.getBean(NowDataService.class); -// BuildingService buildingService = context.getBean(BuildingService.class); -// AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); -// -// public void serialPortSend(String sort,String thread) { -// //查看所有串口 -// SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil(); -// ArrayList port = serialPortUtil.findPort(); -// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); -// Date date = new Date(); -// String dateStr = df.format(date); -// -//// SerialTool serialPortUtil = SerialTool.getSerialPortUtil(); -//// ArrayList port = serialPortUtil.findPort(); -//// comName=comName.toUpperCase(); //转为大写 -//// if (port.contains(comName)){ -// try{ -// //生成对应的采集指令 -// if (sort.equals("1")){ //水温、水位 -// deviceManageEntityList = deviceCodeParamService.queryCodeParam3(thread); -// }else if (sort.equals("2")){ //采集水、电、运行状态! -// deviceManageEntityList = deviceCodeParamService.queryCodeParam4(thread); -// }else if (sort.equals("3")){ //采集设定温度、设定水位、故障状态! -// deviceManageEntityList = deviceCodeParamService.queryCodeParam5(thread); -// }else{ -// deviceManageEntityList = deviceCodeParamService.queryCodeParam3(thread); -// } -// size = deviceManageEntityList.size(); -// for (int i=0;i", e); -// } -// receiveStr=""; -// //从串口读取数据 -// byte[] bytes= serialPortUtil.readFromPort(serialPort); -// try { -// String byteStr = new String(bytes, 0, bytes.length).trim(); -// } catch (NullPointerException e) { -// serialPortUtil.closePort(serialPort); -// Thread.sleep(2000); -// log.info("串口"+serialPort+"没有数据返回!"+i); -// log.info("----------------"+deviceType+"离线,设备号:"+deviceAddr+",所属楼栋:"+buildingName+"----------------"); -// Constant.WEB_FLAG=false;//可以采集的状态 -// if(i==size-1){ -// Constant.FLAG=false; -// } -// String time1=deviceInstallService.selectLastDate(deviceType,deviceAddr,buildingId); -// Date date1=new Date(); -// String time2=df.format(date1); -// if (time1==null){ -// time1=df.format(date1); -// } -// int d= ExchangeStringUtil.compareCopyTime(time1,time2); -// if (d==1){ -// deviceInstallService.updateNotOnline(deviceAddr,deviceType,buildingId,"离线"); //所有设备离线 -// if (deviceType.equals("热泵")){ -// nowDataService.updateRunState(buildingId,deviceAddr,"离线", buildingName); //监控界面状态表热泵在线状态 -// } -// } -// continue; -// } -// receiveStr = receiveStr + printHexString(bytes); -// //去掉空格和null -// receiveStr = receiveStr.replace("null", ""); -// receiveStr = receiveStr.replace(" ", ""); -// log.info("串口"+serialPort+"接受第"+i+"数据:" + receiveStr + ",大小: " + receiveStr.length()); -// try{ -// serialPortUtil.closePort(serialPort); -// log.info("关闭"+serialPort); -// }catch (Exception e){ -//// e.printStackTrace(); -// Constant.WEB_FLAG=false;//可以采集的状态 -// if(i==size-1){ -// Constant.FLAG=false; -// } -// log.error("关闭"+serialPort+"失败!"); -// } -// //返回值全部变成大写 -// String receiveData = receiveStr.toUpperCase(); -// //截取去掉FE -// String dataStr; -// if (receiveData.length()>8){ -// String str1=receiveData.substring(0,8); -// String str2=receiveData.substring(8); -// dataStr=str1.replace("FE", "")+str2; -// }else{ -// dataStr = receiveData.replace("FE", ""); -// } -// deviceInstallService.updateOnline(deviceAddr,deviceType,buildingId,"在线"); //设备在线 -// log.info("----------------"+deviceType+"在线,设备号:"+deviceAddr+",所属楼栋:"+buildingName+"----------------"); -// if (deviceType.equals("热泵")){ -// String strState=nowDataService.selectState(buildingId,deviceAddr); -// if (strState!=null && strState.equals("离线")){ //采集到数据 -// nowDataService.updateRunState(buildingId,deviceAddr,"不运行", buildingName); //监控界面状态表热泵在线状态 -// } -// } -// try{ -// SerialPortSendReceive2.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, dataStr, analysisReceiveOrder485, nowDataService, buildingName); -// }catch (Exception e){ -//// e.printStackTrace(); -// Constant.WEB_FLAG=false;//可以采集的状态 -// if(i==size-1){ -// Constant.FLAG=false; -// } -// log.error(deviceManageEntityList.get(i).getDeviceType()+"保存数据库失败!"+i); -// } -// Thread.sleep(1000); -// }else{ -// Constant.WEB_FLAG=false;//可以采集的状态 -// if(i==size-1){ -// Constant.FLAG=false; -// } -// log.info("-------------串口:"+comName+"不存在!-------------"); -// } -// if(i==size-1){ -// Constant.FLAG=false; -// log.info("-------------一轮采集完,采集标志Constant.Flag="+Constant.FLAG+"-------------"); -// } -// } -// }catch (Exception e){ -// e.printStackTrace(); -// Constant.WEB_FLAG=false;//可以采集的状态 -// Constant.FLAG=false; -// log.error("-------------串口采集异常!-------------"); -// } -//// }else { -//// log.info("串口:"+comName+"不存在!"); -//// } -// } -// /** -// * 字节数组转16进制字符串 -// * @param b 字节数组 -// * @return 16进制字符串 -// */ -// public static String printHexString(byte[] b) { -// StringBuilder sbf = new StringBuilder(); -// for (byte value : b) { -// String hex = Integer.toHexString(value & 0xFF); -// if (hex.length() == 1) { -// hex = '0' + hex; -// } -// sbf.append(hex.toUpperCase()).append(" "); -// } -// return sbf.toString().trim(); -// } -// -// /** -// * 十六进制字符串转byte[] -// * @param hex 十六进制字符串 -// * @return byte[] -// */ -// public static byte[] hexStr2Byte(String hex) { -// if (hex == null) { -// return new byte[] {}; -// } -// -// // 奇数位补0 -// if (hex.length() % 2 != 0) { -// hex = "0" + hex; -// } -// -// int length = hex.length(); -// ByteBuffer buffer = ByteBuffer.allocate(length / 2); -// for (int i = 0; i < length; i++) { -// String hexStr = hex.charAt(i) + ""; -// i++; -// hexStr += hex.charAt(i); -// byte b = (byte) Integer.parseInt(hexStr, 16); -// buffer.put(b); -// } -// return buffer.array(); -// } -// -// /** -// * 16进制转换成为string类型字符串 -// * @param s 待转换字符串 -// */ -// public static String hexStringToString(String s) { -// if (s == null || "".equals(s)) { -// return null; -// } -// s = s.replace(" ", ""); -// byte[] baKeyword = new byte[s.length() / 2]; -// for (int i = 0; i < baKeyword.length; i++) { -// try { -// baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } -// try { -// s = new String(baKeyword, StandardCharsets.UTF_8); -// } catch (Exception e1) { -// e1.printStackTrace(); -// } -// return s; -// } -//} diff --git a/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive2.java b/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive2.java index 1f189d5..02b6f7d 100644 --- a/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive2.java +++ b/user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive2.java @@ -209,7 +209,6 @@ public class SerialPortSendReceive2 { String buildingName) { if ((dataStr.length() == 36 || dataStr.length() == 44 || dataStr.length() == 40 || dataStr.length() == 50) && deviceType.equals("电表")) { analysisReceiveOrder485.analysisMeterOrder485(dataStr, registerAddr, brand, buildingId, buildingName); - nowDataService.proWaterLevel(dateStr, buildingId, ""); //保存时间点楼栋水位 } else if ((dataStr.length() == 18 || dataStr.length() == 70 || dataStr.length() == 44) && deviceType.equals("水表")) { analysisReceiveOrder485.analysisWtMeterOrder485(dataStr, registerAddr, brand, buildingId, buildingName); } else if (deviceType.equals("压变")) { @@ -252,57 +251,4 @@ public class SerialPortSendReceive2 { } } - /** - * 十六进制字符串转byte[] - * - * @param hex 十六进制字符串 - * @return byte[] - */ - public static byte[] hexStr2Byte(String hex) { - if (hex == null) { - return new byte[]{}; - } - - // 奇数位补0 - if (hex.length() % 2 != 0) { - hex = "0" + hex; - } - - int length = hex.length(); - ByteBuffer buffer = ByteBuffer.allocate(length / 2); - for (int i = 0; i < length; i++) { - String hexStr = hex.charAt(i) + ""; - i++; - hexStr += hex.charAt(i); - byte b = (byte) Integer.parseInt(hexStr, 16); - buffer.put(b); - } - return buffer.array(); - } - - /** - * 16进制转换成为string类型字符串 - * - * @param s 待转换字符串 - */ - public static String hexStringToString(String s) { - if (s == null || "".equals(s)) { - return null; - } - s = s.replace(" ", ""); - byte[] baKeyword = new byte[s.length() / 2]; - for (int i = 0; i < baKeyword.length; i++) { - try { - baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); - } catch (Exception e) { - e.printStackTrace(); - } - } - try { - s = new String(baKeyword, StandardCharsets.UTF_8); - } catch (Exception e1) { - e1.printStackTrace(); - } - return s; - } } diff --git a/user-service/src/main/java/com/mh/user/serialport/SerialPortSingle2.java b/user-service/src/main/java/com/mh/user/serialport/SerialPortSingle2.java index a03f20c..dc20d3a 100644 --- a/user-service/src/main/java/com/mh/user/serialport/SerialPortSingle2.java +++ b/user-service/src/main/java/com/mh/user/serialport/SerialPortSingle2.java @@ -3,14 +3,19 @@ package com.mh.user.serialport; import com.mh.common.utils.StringUtils; import com.mh.user.constants.Constant; import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.factory.Device; +import com.mh.user.factory.DeviceFactory; import com.mh.user.service.BuildingService; import com.mh.user.service.DeviceInstallService; import com.mh.user.service.NowDataService; +import com.mh.user.strategy.DeviceStrategy; +import com.mh.user.strategy.DeviceStrategyFactory; import com.mh.user.utils.*; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; import java.io.IOException; +import java.util.Date; import purejavacomm.SerialPort; import purejavacomm.SerialPortEvent; @@ -38,111 +43,115 @@ public class SerialPortSingle2 { String rtData = "fail"; String comName = deviceCodeParamEntity.getDataCom().toUpperCase(); try { - try { - int baudrate = deviceCodeParamEntity.getBaudrate(); - String parity = deviceCodeParamEntity.getParity(); - if (parity == null || parity.equals("") || parity.equalsIgnoreCase("none")) { - serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); - } else { - serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN); + int baudrate = deviceCodeParamEntity.getBaudrate(); + String parity = deviceCodeParamEntity.getParity(); + if (parity == null || parity.equals("") || parity.equalsIgnoreCase("none")) { + serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); + } else { + serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN); + } + // 创建设备报文 + Device device = DeviceFactory.createDevice(deviceCodeParamEntity.getDeviceType()); + if (serialPort != null) { + //向串口发送指令 + log.info("-----------------------------单抄向串口" + serialPort.getName() + "发送指令!-----------------------------"); +// String sendStr = SendOrderUtils.getSendStr(deviceCodeParamEntity); + DeviceStrategy strategy = DeviceStrategyFactory.createStrategy(deviceCodeParamEntity.getDeviceType()); + if (null == strategy) { + return rtData; } - if (serialPort != null) { - //向串口发送指令 - log.info("-----------------------------单抄向串口" + serialPort.getName() + "发送指令!-----------------------------"); - String sendStr = SendOrderUtils.getSendStr(deviceCodeParamEntity); - SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceCodeParamEntity.getDeviceType()); - CacheTools.initReceiveMsg(serialPort.getName()); - SerialPort finalSerialPort = serialPort; - SerialTool.addListener(serialPortEvent -> { - try { - for (int i = 0; i < 5; i++) { - Thread.sleep(1000); - byte[] bytes = SerialTool.readFromPort(finalSerialPort); - if (bytes!= null && bytes.length > 0) { - if (Constant.WEB_FLAG) { - CacheTools.setReceiveMsg(finalSerialPort.getName(), ExchangeStringUtil.printHexString(bytes)); - break; - } + device.setStrategy(strategy); + String sendStr = device.createOrders(deviceCodeParamEntity); + + SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceCodeParamEntity.getDeviceType()); + CacheTools.initReceiveMsg(serialPort.getName()); + SerialPort finalSerialPort = serialPort; + SerialTool.addListener(serialPortEvent -> { + try { + for (int i = 0; i < 5; i++) { + Thread.sleep(1000); + byte[] bytes = SerialTool.readFromPort(finalSerialPort); + if (bytes!= null && bytes.length > 0) { + if (Constant.WEB_FLAG) { + CacheTools.setReceiveMsg(finalSerialPort.getName(), ExchangeStringUtil.printHexString(bytes)); + break; } } - } catch (Exception e) { - log.error("单抄串口" + finalSerialPort + "异常,关闭串口", e); } - }, serialPort); - } - } catch (Exception e) { - SerialTool.closePort(serialPort); - log.info("单抄串口" + serialPort + "异常,没有数据返回!关闭串口", e); - return "fail"; + } catch (Exception e) { + log.error("单抄串口" + finalSerialPort + "异常,关闭串口", e); + } + }, serialPort); } String receiveStr; - if (serialPort != null) { - receiveStr = CacheTools.waitReceiveMsg(serialPort.getName()); - //去掉空格和null - if (StringUtils.isBlank(receiveStr)) { - return "fail"; - } - receiveStr = receiveStr.replace("null", "").replace(" ", ""); - log.info("串口" + serialPort.getName() + "接收数据:" + receiveStr + ",大小: " + receiveStr.length()); - //返回值全部变成大写 - String receiveData = receiveStr.toUpperCase(); - //截取去掉FE - String deviceType = deviceCodeParamEntity.getDeviceType(); - String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); - String dataStr = ""; - if (receiveData.length() > 8 && ("水表".equals(deviceType) || "电表".equals(deviceType))) { - String str1 = receiveData.substring(0, 8); - String str2 = receiveData.substring(8); - dataStr = str1.replace("FE", "") + str2; - } else { - dataStr = receiveData; - } - String registerAddr = deviceCodeParamEntity.getRegisterAddr(); - String brand = deviceCodeParamEntity.getBrand(); - String buildingId = deviceCodeParamEntity.getBuildingId(); - String buildingName = buildingService.queryBuildingName(buildingId); //查询楼栋名称 - - deviceInstallService.updateOnline(deviceAddr, deviceType, buildingId, "在线"); //设备在线 - log.info(deviceType + "在线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName); - if (deviceType.equals("热泵")) { - String strState = nowDataService.selectState(buildingId, deviceAddr); - if (strState != null && strState.equals("离线")) { //采集到数据 - nowDataService.updateRunState(buildingId, deviceAddr, "不运行", buildingName); //监控界面状态表热泵在线状态 - } - } - try { - if ((dataStr.length() == 18 || dataStr.length() == 70 || dataStr.length() == 72 || dataStr.length() == 44) && deviceType.equals("水表")) { - rtData = analysisReceiveOrder485.analysisWtMeterOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - } else if ((dataStr.length() == 36 || dataStr.length() == 44 || dataStr.length() == 40 || dataStr.length() == 50) && deviceType.equals("电表")) { - rtData = analysisReceiveOrder485.analysisMeterOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - } else if (deviceType.equals("压变")) { - rtData = analysisReceiveOrder485.analysisPressureOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - } else if ((dataStr.length() == 30) && deviceType.equals("状态检测")) {//五路状态读取,兼容旧版系统 - analysisReceiveOrder485.analysisStateOrder485(dataStr, registerAddr, brand, buildingId, buildingName); - } else if (deviceType.equals("水位开关") && (StringUtils.isBlank(registerAddr) || (registerAddr.equals("0018") || registerAddr.equals("0017")))) { - rtData = analysisReceiveOrder485.analysisRelayOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - log.info("水位开关读取或者设置返回值==>{}", rtData); - } else if (deviceType.equals("热泵")) { - rtData = analysisReceiveOrder485.analysisPumpOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - } else if (deviceType.equals("时控")) { - rtData = analysisReceiveOrder485.analysisTimeSetOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - log.info("时控读取或者设置返回值==>{}", rtData); - } else if (deviceType.equals("水位开关") && !StringUtils.isBlank(registerAddr) && registerAddr.equals("0010")) { //热泵状态 - rtData = analysisReceiveOrder485.analysisPumpStateOrder2(dataStr, registerAddr, brand, buildingId, buildingName); - } else if (deviceType.equals("温度变送器")) { - rtData = analysisReceiveOrder485.analysisMulTempOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); - } else if (deviceType.equals("热泵状态")) { - rtData = analysisReceiveOrder485.analysisPumpStateOrder2(dataStr, registerAddr, brand, buildingId, buildingName); - } - } catch (Exception e) { - log.error(deviceCodeParamEntity.getDeviceType() + "单抄保存数据库失败!", e); - SerialTool.closePort(serialPort); - return "fail"; - } - } else { + if (serialPort == null) { log.info("串口为空,无法进行采集控制"); return "fail"; } + receiveStr = CacheTools.waitReceiveMsg(serialPort.getName()); + //去掉空格和null + if (StringUtils.isBlank(receiveStr)) { + return "fail"; + } + receiveStr = receiveStr.replace("null", "").replace(" ", ""); + log.info("串口" + serialPort.getName() + "接收数据:" + receiveStr + ",大小: " + receiveStr.length()); + //返回值全部变成大写 + String receiveData = receiveStr.toUpperCase(); + //截取去掉FE + String deviceType = deviceCodeParamEntity.getDeviceType(); + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String dataStr = ""; + if (receiveData.length() > 8 && ("水表".equals(deviceType) || "电表".equals(deviceType))) { + String str1 = receiveData.substring(0, 8); + String str2 = receiveData.substring(8); + dataStr = str1.replace("FE", "") + str2; + } else { + dataStr = receiveData; + } + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String buildingId = deviceCodeParamEntity.getBuildingId(); + String buildingName = buildingService.queryBuildingName(buildingId); //查询楼栋名称 + + deviceInstallService.updateOnline(deviceAddr, deviceType, buildingId, "在线"); //设备在线 + log.info(deviceType + "在线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName); + if (deviceType.equals("热泵")) { + String strState = nowDataService.selectState(buildingId, deviceAddr); + if (strState != null && strState.equals("离线")) { //采集到数据 + nowDataService.updateRunState(buildingId, deviceAddr, "不运行", buildingName); //监控界面状态表热泵在线状态 + } + } +// try { +// if ((dataStr.length() == 18 || dataStr.length() == 70 || dataStr.length() == 72 || dataStr.length() == 44) && deviceType.equals("水表")) { +// rtData = analysisReceiveOrder485.analysisWtMeterOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if ((dataStr.length() == 36 || dataStr.length() == 44 || dataStr.length() == 40 || dataStr.length() == 50) && deviceType.equals("电表")) { +// rtData = analysisReceiveOrder485.analysisMeterOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if (deviceType.equals("压变")) { +// rtData = analysisReceiveOrder485.analysisPressureOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if ((dataStr.length() == 30) && deviceType.equals("状态检测")) {//五路状态读取,兼容旧版系统 +// analysisReceiveOrder485.analysisStateOrder485(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if (deviceType.equals("水位开关") && (StringUtils.isBlank(registerAddr) || (registerAddr.equals("0018") || registerAddr.equals("0017")))) { +// rtData = analysisReceiveOrder485.analysisRelayOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// log.info("水位开关读取或者设置返回值==>{}", rtData); +// } else if (deviceType.equals("热泵")) { +// rtData = analysisReceiveOrder485.analysisPumpOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if (deviceType.equals("时控")) { +// rtData = analysisReceiveOrder485.analysisTimeSetOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// log.info("时控读取或者设置返回值==>{}", rtData); +// } else if (deviceType.equals("水位开关") && !StringUtils.isBlank(registerAddr) && registerAddr.equals("0010")) { //热泵状态 +// rtData = analysisReceiveOrder485.analysisPumpStateOrder2(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if (deviceType.equals("温度变送器")) { +// rtData = analysisReceiveOrder485.analysisMulTempOrder4852(dataStr, registerAddr, brand, buildingId, buildingName); +// } else if (deviceType.equals("热泵状态")) { +// rtData = analysisReceiveOrder485.analysisPumpStateOrder2(dataStr, registerAddr, brand, buildingId, buildingName); +// } +// } catch (Exception e) { +// log.error(deviceCodeParamEntity.getDeviceType() + "单抄保存数据库失败!", e); +// SerialTool.closePort(serialPort); +// return "fail"; +// } + rtData = device.analysisReceiveData(DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"), + deviceType, registerAddr, brand, buildingId, buildingName, dataStr); SerialTool.closePort(serialPort); Thread.sleep(200); log.info("-----------------------------" + serialPort.getName() + "单抄结束!-----------------------------"); diff --git a/user-service/src/main/java/com/mh/user/serialport/SerialPortThread.java b/user-service/src/main/java/com/mh/user/serialport/SerialPortThread.java index f368d6c..668ce3c 100644 --- a/user-service/src/main/java/com/mh/user/serialport/SerialPortThread.java +++ b/user-service/src/main/java/com/mh/user/serialport/SerialPortThread.java @@ -37,8 +37,10 @@ public class SerialPortThread implements Runnable{ public void run(){ log.info("创建发送接收数据线程>>>>>>>>>>>>>>"+thread); - SerialPortSendReceive2 serial=new SerialPortSendReceive2(); - serial.serialPortSend(name,thread); +// SerialPortSendReceive2 serial=new SerialPortSendReceive2(); +// serial.serialPortSend(name,thread); + SendAndReceiveByCom sendAndReceiveByCom = new SendAndReceiveByCom(); + sendAndReceiveByCom.sendAndReceive(name,thread); this.countDownLatch.countDown(); } } diff --git a/user-service/src/main/java/com/mh/user/strategy/DeviceStrategy.java b/user-service/src/main/java/com/mh/user/strategy/DeviceStrategy.java new file mode 100644 index 0000000..780cd29 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/DeviceStrategy.java @@ -0,0 +1,20 @@ +package com.mh.user.strategy; + +import com.mh.user.entity.DeviceCodeParamEntity; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 设备操作策略模式 + * @date 2024-03-15 16:25:43 + */ +public interface DeviceStrategy { + + /** + * 根据读,写方式创建报文 + */ + String createOrders(DeviceCodeParamEntity deviceCodeParamEntity); + + String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr); +} diff --git a/user-service/src/main/java/com/mh/user/strategy/DeviceStrategyFactory.java b/user-service/src/main/java/com/mh/user/strategy/DeviceStrategyFactory.java new file mode 100644 index 0000000..ccf9746 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/DeviceStrategyFactory.java @@ -0,0 +1,18 @@ +package com.mh.user.strategy; + +import com.mh.user.constants.DeviceStrategyEnum; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 策略工厂类 + * @date 2024-03-18 11:23:38 + */ +public class DeviceStrategyFactory { + + public static DeviceStrategy createStrategy(String deviceType) { + return DeviceStrategyEnum.getDeviceStrategy(deviceType); + } + +} diff --git a/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java b/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java new file mode 100644 index 0000000..27ff6c3 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java @@ -0,0 +1,119 @@ +package com.mh.user.strategy; + +import com.mh.common.utils.StringUtils; +import com.mh.user.entity.DataResultEntity; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.service.DataResultService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.Date; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 电表运行策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class EleMeterStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + DataResultService dataResultService = context.getBean(DataResultService.class); + + private static class SingletonHolder { + private static final EleMeterStrategy INSTANCE = new EleMeterStrategy(); + } + + private EleMeterStrategy() { + // 防止外部直接实例化 + } + + public static EleMeterStrategy getInstance() { + return EleMeterStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String str = ""; + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + //0代表前面补充0,12代表长度为12,d代表参数为正数型,基表通讯号 + str = String.format("%012d", Long.parseLong(deviceAddr)); + //转换位置 + str = ExchangeStringUtil.changePosition(str); + //拼接功能码 + str = "68" + str + "680102"; + String strData = "1090"; + //加33操作 + str = str + ExchangeStringUtil.addThree(strData); + //检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str); + str = "FEFEFE" + str + checkSum + "16"; + } catch (Exception e) { + log.error("生成采集电表指令错误==>", e); + } + } + log.info("生成采集电表指令==>" + str); + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String data = ""; + if (dataStr.length() == 36 || dataStr.length() == 40 || dataStr.length() == 44 || dataStr.length() == 50) { + String checkStr = dataStr.substring(0, dataStr.length() - 4); //减去校验码 + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + //返回的校验码与重新生成的校验码进行校验 + if (checkNum.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4, dataStr.length() - 2))) { + //表号,12位 + String meterId = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) + + checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); + meterId = String.format("%012d", Long.parseLong(meterId)); + StringBuilder stringBuilder = new StringBuilder(); + if (dataStr.length() == 36) { + for (int i = 0; i < 4; i++) { + String data1 = checkStr.substring(32 - 2 * (i + 1), 32 - 2 * i); + stringBuilder.append(data1); + } + } else { + for (int i = 0; i < 4; i++) { + String data1 = checkStr.substring(36 - 2 * (i + 1), 36 - 2 * i); + stringBuilder.append(data1); + } + } + data = stringBuilder.toString(); + data = ExchangeStringUtil.cutThree(data); + // 0 代表前面补充0,4 代表长度为4,d 代表参数为正数型 + data = String.format("%08d", Long.parseLong(data)); + data = data.substring(0, 6) + "." + data.substring(6, 8); + log.info("电表表号:" + meterId + ",电表读数:" + data); + try { + DataResultEntity dataResultEntity = new DataResultEntity(); + dataResultEntity.setDeviceAddr(meterId);//通讯编号 + dataResultEntity.setDeviceType("电表"); + dataResultEntity.setBuildingId(buildingId); + dataResultEntity.setCurValue(Double.parseDouble(data)); //当前读数 + Date date = new Date(); + dataResultEntity.setCurDate(date); //当前日期 + dataResultService.saveDataResult(dataResultEntity); + log.info("电表数据保存数据库成功! 楼栋名称:" + buildingName); + } catch (Exception e) { + log.error("电表数据保存数据库失败!楼栋名称:" + buildingName, e); + } + } else { + log.info("电表报文检验失败: " + dataStr); + } + } + if (!StringUtils.isBlank(data)) { + data = String.valueOf(Double.valueOf(data)); //00010.76,去除读数前面带0的情况 + } + return data; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/HeatPumpStatusStrategy.java b/user-service/src/main/java/com/mh/user/strategy/HeatPumpStatusStrategy.java new file mode 100644 index 0000000..dfa34bc --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/HeatPumpStatusStrategy.java @@ -0,0 +1,241 @@ +package com.mh.user.strategy; + +import com.alibaba.fastjson2.JSON; +import com.mh.common.utils.StringUtils; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.service.BuildingService; +import com.mh.user.service.NowDataService; +import com.mh.user.service.NowPublicDataService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 热泵状态 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class HeatPumpStatusStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + BuildingService buildingService = context.getBean(BuildingService.class); + + private static class SingletonHolder { + private static final HeatPumpStatusStrategy INSTANCE = new HeatPumpStatusStrategy(); + } + + private HeatPumpStatusStrategy() { + // 防止外部直接实例化 + } + + public static HeatPumpStatusStrategy getInstance() { + return HeatPumpStatusStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String funCode = deviceCodeParamEntity.getFunCode(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + if (StringUtils.isBlank(brand) || Constant.BRAND_ZHONG_KAI.equals(brand)) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + str = "33" + str + "1700000000"; //旧版继电器 + // 检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str); + str = str + checkSum; + } else if (Constant.BRAND_YUAN_XIANG.equals(brand)) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + str = str + "0300100008"; + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } else if (Constant.BRAND_DING_WEI.equals(brand)) { + str = String.format("%012d", Long.parseLong(deviceAddr)); + //转换位置 + str = ExchangeStringUtil.changePosition(str); //表号 + String strData = ""; + str = "68" + str + "680102"; + strData = "25C0"; //标志 + // } + strData = ExchangeStringUtil.addThree(strData); //加33 + str = str + strData; + //检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str);//校验 + str = "FEFEFE" + str + checkSum + "16"; + } + } catch (Exception e) { + log.error("生成热泵状态指令出错!" + str, e); + } + } + log.info("生成热泵状态采集指令>>>>" + str); + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String receiveData) { + String result = Constant.FAIL; + String l1 = ""; + String l2 = ""; + String l3 = ""; + String l4 = ""; + String l5 = ""; + String l6 = ""; + String l7 = ""; + String l8 = ""; + String runState = ""; + String addr = ""; + Map map = new HashMap(); + String checkStr = receiveData.substring(0, receiveData.length() - 4); //检验报文减,去校验码 + if (StringUtils.isBlank(brand) || brand.equals("顶威")) { + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) { + //表号,12位 + addr = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) + + checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); + addr = addr.replaceAll("^0*", ""); + String data = checkStr.substring(24, 26); //截取数值 + data = ExchangeStringUtil.cutThree(data); + String strStatus = ExchangeStringUtil.hexString2binaryString(data); + strStatus = String.format("%08d", Long.parseLong(strStatus)); + if (strStatus.charAt(7) == '1') { + l1 = "1"; + } else { + l1 = "0"; + } + if (strStatus.charAt(6) == '1') { + l2 = "1"; + } else { + l2 = "0"; + } + if (strStatus.charAt(5) == '1') { + l3 = "1"; + } else { + l3 = "0"; + } + if (strStatus.charAt(4) == '1') { + l4 = "1"; + } else { + l4 = "0"; + } + if (strStatus.charAt(3) == '1') { + l5 = "1"; + } else { + l5 = "0"; + } + if (strStatus.charAt(2) == '1') { + l6 = "1"; + } else { + l6 = "0"; + } + if (strStatus.charAt(1) == '1') { + l7 = "1"; + } else { + l7 = "0"; + } + if (strStatus.charAt(0) == '1') { + l8 = "1"; + } else { + l8 = "0"; + } + } + } else if (brand.equals("中凯")) { + addr = ExchangeStringUtil.hexToDec(checkStr.substring(2, 4)); + l1 = checkStr.substring(4, 6); + l2 = checkStr.substring(20, 22); + l3 = checkStr.substring(36, 38); + l4 = checkStr.substring(52, 54); + l5 = checkStr.substring(68, 70); + l6 = checkStr.substring(84, 86); + l7 = checkStr.substring(100, 102); + l8 = checkStr.substring(116, 118); + } else if (brand.equals("远向")) { + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr); + if (checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { + addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + l1 = checkStr.substring(6, 10); + l2 = checkStr.substring(10, 14); + l3 = checkStr.substring(14, 18); + l4 = checkStr.substring(18, 22); + l5 = checkStr.substring(22, 26); + l6 = checkStr.substring(26, 30); + l7 = checkStr.substring(30, 34); + l8 = checkStr.substring(34, 38); + } else { + log.info("热泵状态报文检验失败: " + receiveData); + } + } + if (l1.equals("12") || l1.equals("0001")) { //正常是0001 + map.put("1", "运行"); + } else { + map.put("1", "不运行"); + } + if (l2.equals("12") || l2.equals("0001")) { + map.put("2", "运行"); + } else { + map.put("2", "不运行"); + } + if (l3.equals("12") || l3.equals("0001")) { + map.put("3", "运行"); + } else { + map.put("3", "不运行"); + } + if (l4.equals("12") || l4.equals("0001")) { + map.put("4", "运行"); + } else { + map.put("4", "不运行"); + } + if (l5.equals("12") || l5.equals("0001")) { + map.put("5", "运行"); + } else { + map.put("5", "不运行"); + } + if (l6.equals("12") || l6.equals("0001")) { + map.put("6", "运行"); + } else { + map.put("6", "不运行"); + } + if (l7.equals("12") || l7.equals("0001")) { + map.put("7", "运行"); + } else { + map.put("7", "不运行"); + } + if (l8.equals("12") || l8.equals("0001")) { + map.put("8", "运行"); + } else { + map.put("8", "不运行"); + } + int count = buildingService.selectPumpCount(buildingId); //楼栋热泵数 + if (count > 0) { + for (Map.Entry entry : map.entrySet()) { + addr = entry.getKey(); //获取Key值作为热泵ID + runState = entry.getValue(); + if (addr != null && Integer.parseInt(addr) <= count) { + nowDataService.saveNowHistoryData3(addr, "热泵状态", runState, "runState", buildingId); + nowDataService.proPumpMinutes(buildingId, addr, runState); //计算热泵运行时长 + nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存时间点温度 + log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + runState); + } + } + log.info("热泵状态号:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); + result = JSON.toJSONString(map); //map转json字符串 + } + return result; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/HeatPumpStrategy.java b/user-service/src/main/java/com/mh/user/strategy/HeatPumpStrategy.java new file mode 100644 index 0000000..5167737 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/HeatPumpStrategy.java @@ -0,0 +1,398 @@ +package com.mh.user.strategy; + +import com.mh.common.utils.StringUtils; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.entity.NowPublicDataEntity; +import com.mh.user.service.*; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 热泵策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class HeatPumpStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + PumpSetService pumpSetService = context.getBean(PumpSetService.class); + DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class); + + private static class SingletonHolder { + private static final HeatPumpStrategy INSTANCE = new HeatPumpStrategy(); + } + + private HeatPumpStrategy() { + // 防止外部直接实例化 + } + + public static HeatPumpStrategy getInstance() { + return HeatPumpStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String funCode = deviceCodeParamEntity.getFunCode(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String dataValue = deviceCodeParamEntity.getDataValue(); + String str = ""; + String param = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + // 0代表前面补充0,2代表长度为2,d代表参数为正数型 + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + if (StringUtils.isBlank(brand) || Constant.BRAND_MEI_DI.equals(brand)) { + if (StringUtils.isBlank(funCode) || funCode.equals("03")) { + if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0641")) { // 运行状态 + str = str + "0306410001"; + param = "运行状态"; + } else if (registerAddr.equalsIgnoreCase("0007")) { // 水温 + str = str + "0300070001"; + param = "实际温度"; + } else if (registerAddr.equalsIgnoreCase("000B")) { // 故障状态,100*N+11 + str = str + "03000B0001"; + param = "故障状态"; + } else if (registerAddr.equalsIgnoreCase("0642")) { // 读温度设定 + str = str + "0306420001"; + param = "设定温度"; + } else if (registerAddr.equalsIgnoreCase("0656")) { //读时段1 + str = str + "0306560004"; + param = "时段1"; + } else if (registerAddr.equalsIgnoreCase("065A")) { //读时段2 + str = str + "03065A0004"; + param = "时段2"; + } + } else {//10 + if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0642")) {//温度设定,写 + str = str + "100642000102" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试 + } else { + if (dataValue.length() == 8) { + String strData = "00" + dataValue.substring(0, 2) + "00" + dataValue.substring(2, 4) + "00" + dataValue.substring(4, 6) + "00" + dataValue.substring(6, 8); + if (registerAddr.equalsIgnoreCase("0656")) {//时段1 + str = str + "100656000408" + strData; //写 + } else if (registerAddr.equalsIgnoreCase("065A")) {//时段2 + str = str + "10065A000408" + strData; //写 + } + } + } + } + } else if (Constant.BRAND_MEI_DI_TWO.equals(brand)) { + if (StringUtils.isBlank(funCode) || funCode.equals("03")) { + if (registerAddr == null || registerAddr.equals("") || registerAddr.equalsIgnoreCase("0BBD")) { // 运行状态 + str = str + "030BBD0001"; + param = "运行状态"; + } else if (registerAddr.equalsIgnoreCase("0064")) { // 水温 + str = str + "0300640001"; + param = "实际温度"; + } else if (registerAddr.equalsIgnoreCase("0BBB")) { // 故障状态 + str = str + "030BBB0001"; + param = "故障状态"; + } else if (registerAddr.equalsIgnoreCase("0003")) { // 读温度设定 + str = str + "0300030001"; + param = "设定温度"; + } + } else {//06 + if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0003")) {//温度设定,写 + str = str + "060003" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试 + } else if (registerAddr.equals("0000")) {//开关机 + if (dataValue.equals("0000")) { + str = str + "0600000000"; //关机 + } else { + str = str + "0600000003"; //制热水,开机 + } + } + } + } else if (Constant.BRAND_RUI_XING.equals(brand)) { + if (StringUtils.isBlank(funCode) || funCode.equals("03")) { + if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0001")) { // 运行状态 + str = str + "0300010001"; + param = "运行状态"; + } else if (registerAddr.equalsIgnoreCase("0046")) { // 水温 + str = str + "0300460001"; + param = "实际温度"; + } else if (registerAddr.equalsIgnoreCase("0050")) { // 故障状态,100*N+11 + str = str + "0300500001"; + param = "故障状态"; + } else if (registerAddr.equalsIgnoreCase("000A")) { // 读温度设定 + str = str + "03000A0001"; + param = "设定温度"; + } else if (registerAddr.equalsIgnoreCase("0028")) { //读时段1 + str = str + "0300280004"; + param = "时段1"; + } else if (registerAddr.equalsIgnoreCase("002C")) { //读时段2 + str = str + "03002C0004"; + param = "时段2"; + } + } else if ("06".equals(funCode)) { + str = str + funCode + registerAddr;// 定时开机开关机 + if ("0023".equals(registerAddr)) { + param = "时段1"; + } else { + param = "时段2"; + } + } else {//10 + if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("000A")) {//温度设定,写 + str = str + "10000A000102" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试 + } else if (registerAddr.equalsIgnoreCase("0028") || registerAddr.equalsIgnoreCase("002C")) {//时段1 + if (dataValue.length() == 8) { + String strData = "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(0, 2))),2) + + "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(2, 4))),2) + + "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(4, 6))),2) + + "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(6, 8))),2); + str = str + "10"+registerAddr+"000408" + strData; //写 + } + } + } + } + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } catch (Exception e) { + log.info("热泵" + param + "指令>>>>异常" + str, e); + } + } + log.info("热泵" + param + "指令>>>>" + str); + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String checkStr = dataStr.substring(0, dataStr.length() - 4);//检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码 + String sValue = null; + String dataType = null; + String rtData = Constant.FAIL; + if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + log.info("热泵报文检验失败: " + dataStr); + return Constant.FAIL; + } + String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + String data = ""; + if (StringUtils.isBlank(brand) || Constant.BRAND_MEI_DI.equals(brand)) { + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {//读 + if (registerAddr.equalsIgnoreCase("0641")) { //运行状态 + dataType = "runState"; + data = checkStr.substring(8, 10); + log.info("------------美的热泵状态值-----------" + data); + if (data.equalsIgnoreCase("08")) { + sValue = "不运行"; //关机模式 + } else if (data.equalsIgnoreCase("01")) { + sValue = "运行"; //制冷模式 + } else if (data.equalsIgnoreCase("02")) { + sValue = "运行"; //制热模式 + } else if (data.equalsIgnoreCase("04")) { + sValue = "运行"; //水泵模式 + } else if (data.equalsIgnoreCase("10")) { + sValue = "运行"; //制热水模式 + } + //计算热泵运行时间,按分钟 + nowDataService.proPumpMinutes(buildingId, addr, sValue); + log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); + } else if (registerAddr.equalsIgnoreCase("0642") || registerAddr.equalsIgnoreCase("0007")) { + //0642设定温度,0007水箱水温 + if (registerAddr.equalsIgnoreCase("0642")) { + dataType = "tempSet"; + } else { + dataType = "waterTemp"; + } + //读数 + sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); + if (dataType.equals("waterTemp")) { + String avgTemp = nowDataService.selectAve(buildingId); + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + publicData.setUseWaterTemp(avgTemp); + publicData.setBackWaterTemp(avgTemp); + String pumpId = nowDataService.selectMinPumpId(buildingId); + if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度 + publicData.setSingleTemp(sValue); + log.info("---------------单箱温度:" + sValue + "---------------"); + } + nowPublicDataService.saveNowHistoryPublicData(publicData); + log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); + } else if (dataType.equals("tempSet")) { + pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度 + } + } else if (registerAddr.equalsIgnoreCase("000B")) { //故障状态 + dataType = "isFault"; + String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); + sData = ExchangeStringUtil.addZeroForNum(sData, 8); + if (sData.substring(7, 8).equalsIgnoreCase("0")) { + sValue = "无故障"; + deviceInstallService.updateDeviceFault("0", addr, "热泵"); + } else if (sData.substring(7, 8).equalsIgnoreCase("1")) { + sValue = "有故障"; + deviceInstallService.updateDeviceFault("1", addr, "热泵"); + } + } else if (registerAddr.equalsIgnoreCase("0656") + || registerAddr.equalsIgnoreCase("065A") + || registerAddr.equalsIgnoreCase("065E")) { //读定时设置值 + String startTime = checkStr.substring(8, 10) + checkStr.substring(12, 14); + String closetTime = checkStr.substring(16, 18) + checkStr.substring(20, 22); + sValue = startTime + closetTime; + } + } else if (checkStr.substring(2, 4).equalsIgnoreCase("10")) { + log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); + return Constant.SUCCESS; + } + } else if (Constant.BRAND_MEI_DI_TWO.equals(brand)) { + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读 + if (registerAddr.equalsIgnoreCase("0BBD")) { //运行状态 + dataType = "runState"; + data = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); + data = ExchangeStringUtil.addZeroForNum(data, 8);//二进制数,补够8位 + data = data.substring(4, 8); //截取后四位 + log.info("------------美的2热泵状态值-----------" + data); + if (data.equalsIgnoreCase("0000")) { //0 + sValue = "不运行"; //关机 + } else if (data.equalsIgnoreCase("0001")) {//1 + sValue = "运行"; //水泵 + } else if (data.equalsIgnoreCase("0010")) {//2 + sValue = "运行"; //制冷 + } else if (data.equalsIgnoreCase("0011")) {//3 + sValue = "运行"; //制热 + } else if (data.equalsIgnoreCase("0100")) {//4 + sValue = "运行"; //热水 + } else if (data.equalsIgnoreCase("0101")) {//5 + sValue = "运行"; //采暖 + } else if (data.equalsIgnoreCase("0110")) {//6 + sValue = "运行"; //电热模式 + } + //计算热泵运行时间,按分钟 + nowDataService.proPumpMinutes(buildingId, addr, sValue); + log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); + } else if (registerAddr.equalsIgnoreCase("0003") || registerAddr.equalsIgnoreCase("0064")) { + //0003设定温度,0064水箱水温 + if (registerAddr.equalsIgnoreCase("0003")) { + dataType = "tempSet"; + } else { + dataType = "waterTemp"; + } + //读数 + sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); + if (dataType.equals("waterTemp")) { + String avgTemp = nowDataService.selectAve(buildingId); + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + publicData.setUseWaterTemp(avgTemp); + publicData.setBackWaterTemp(avgTemp); + String pumpId = nowDataService.selectMinPumpId(buildingId); + log.info("---------------addr:" + addr + ",pumpId:" + pumpId + " ---------------"); + if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度 + publicData.setSingleTemp(sValue); + log.info("---------------单箱温度:" + sValue + "---------------"); + } + nowPublicDataService.saveNowHistoryPublicData(publicData); + log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); + } else if (dataType.equals("tempSet")) { + pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度 + } + } else if (registerAddr.equalsIgnoreCase("0BBB")) { //故障状态 + dataType = "isFault"; + String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); + sData = ExchangeStringUtil.addZeroForNum(sData, 8); + if (sData.substring(7, 8).equalsIgnoreCase("0")) { + sValue = "无故障"; + } else if (sData.substring(7, 8).equalsIgnoreCase("1")) { + sValue = "有故障"; + } + } else if (registerAddr.equalsIgnoreCase("0656") + || registerAddr.equalsIgnoreCase("065A") + || registerAddr.equalsIgnoreCase("065E")) { //定时设置值 + String startTime = ExchangeStringUtil.hexToDec(checkStr.substring(8, 10)) + ExchangeStringUtil.hexToDec(checkStr.substring(12, 14)); + String closetTime = ExchangeStringUtil.hexToDec(checkStr.substring(16, 18)) + ExchangeStringUtil.hexToDec(checkStr.substring(20, 22)); + sValue = startTime + closetTime; + } + rtData = sValue; + } else if (checkStr.substring(2, 4).equalsIgnoreCase("06")) { + log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); + return Constant.SUCCESS; + } + } else if (Constant.BRAND_RUI_XING.equals(brand)) { + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {//读 + if (registerAddr.equalsIgnoreCase("0001")) { //运行状态 + dataType = "runState"; + data = checkStr.substring(8, 10); + if (data.equalsIgnoreCase("00")) { + sValue = "不运行"; //关机模式 + } else if (data.equalsIgnoreCase("01")) { + sValue = "运行"; //制热模式 + } + //计算热泵运行时间,按分钟 + nowDataService.proPumpMinutes(buildingId, addr, sValue); + log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); + } else if (registerAddr.equalsIgnoreCase("000A") || registerAddr.equalsIgnoreCase("0046")) { + //000A设定温度,0046水箱水温 + if (registerAddr.equalsIgnoreCase("000A")) { + dataType = "tempSet"; + } else { + dataType = "waterTemp"; + } + //读数 + sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); + if (dataType.equals("waterTemp")) { + sValue = String.valueOf(Double.parseDouble(sValue)/10); + String avgTemp = nowDataService.selectAve(buildingId); + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + publicData.setUseWaterTemp(avgTemp); + publicData.setBackWaterTemp(avgTemp); + String pumpId = nowDataService.selectMinPumpId(buildingId); + log.info("---------------addr:" + addr + ",pumpId:" + pumpId + " ---------------"); + if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度 + publicData.setSingleTemp(sValue); + log.info("---------------单箱温度:" + sValue + "---------------"); + } + nowPublicDataService.saveNowHistoryPublicData(publicData); + log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); + } else if (dataType.equals("tempSet")) { + pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度 + } + } else if (registerAddr.equalsIgnoreCase("0050")) { //故障状态 + dataType = "isFault"; + String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); + sData = ExchangeStringUtil.addZeroForNum(sData, 8); + if (sData.substring(7, 8).equalsIgnoreCase("0")) { + sValue = "无故障"; + deviceInstallService.updateDeviceFault("0", addr, "热泵"); + } else if (sData.substring(7, 8).equalsIgnoreCase("1")) { + sValue = "有故障"; + deviceInstallService.updateDeviceFault("1", addr, "热泵"); + } + } else if (registerAddr.equalsIgnoreCase("0028") + || registerAddr.equalsIgnoreCase("002C") + || registerAddr.equalsIgnoreCase("0030")) { //读定时设置值 + // 01 03 08 0003 0000 0016 0000 4713 + String startTime = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)), 2) + + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(10, 14)), 2); + String closetTime = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(14, 18)), 2) + + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(18, 22)), 2); + sValue = startTime + closetTime; + } + } else if (checkStr.substring(2, 4).equalsIgnoreCase("10")) { + log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); + return Constant.SUCCESS; + } + rtData = sValue; + } + if (!StringUtils.isBlank(sValue)) { + nowDataService.saveNowHistoryData(addr, "热泵", sValue, dataType, buildingId); + log.info("时间: " + dateStr + "热泵ID:" + addr + ",数据: " + sValue + ",保存数据库成功!楼栋名称:" + buildingName); + } + nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存楼栋时间点温度变化 + log.info("----------------保存楼栋时间点温度变化值!----------------"); + return rtData; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/PressureTransStrategy.java b/user-service/src/main/java/com/mh/user/strategy/PressureTransStrategy.java new file mode 100644 index 0000000..dcf97c5 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/PressureTransStrategy.java @@ -0,0 +1,110 @@ +package com.mh.user.strategy; + +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.service.*; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.text.DecimalFormat; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 压力变送器策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class PressureTransStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class); + BuildingService buildingService = context.getBean(BuildingService.class); + + private static class SingletonHolder { + private static final PressureTransStrategy INSTANCE = new PressureTransStrategy(); + } + + private PressureTransStrategy() { + // 防止外部直接实例化 + } + + public static PressureTransStrategy getInstance() { + return PressureTransStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + str = ExchangeStringUtil.decToHex(deviceAddr); //十进制转为十六进制 + str = ExchangeStringUtil.addZeroForNum(str, 2); //以0补位 + if (Constant.BRAND_AU_SUN.equals(brand)) { + str = str + "0300040001"; // 新款压力变送器 + } else if (Constant.BRAND_RU_YI.equals(brand)) { + str = str + "0300040001"; + } else { + str = str + "0300000002"; // 压力变送器(新的协议) + } + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } catch (Exception e) { + log.info("生成压变指令出错!" + str, e); + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String result = "fail"; + String checkStr = dataStr.substring(0, dataStr.length() - 4);// 检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码 + if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + log.info("压变报文检验失败: " + dataStr); + return result; + } + String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + String data = ""; + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读 + double wtHeight = 0.0; + if (brand == null || brand.equals("")) { + float fdata = ExchangeStringUtil.hexToSingle(checkStr.substring(6, 14));//十六进制转浮点型 + wtHeight = fdata * 1.02; //通过压力求水高 + } else if (Constant.BRAND_AU_SUN.equals(brand) || Constant.BRAND_RU_YI.equals(brand)) { + data = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10));//十六进制转整形 + wtHeight = Double.parseDouble(data) / 100 * 0.102; //通过压力求水高 + } + Double tankHeight = buildingService.queryTankHeight(buildingId);//水箱高,从数据库获取 + if (tankHeight == null) { + tankHeight = 2.0; + } + Double wtLevel = wtHeight / tankHeight * 100; //水箱水位 + log.info("------水箱水高:" + wtLevel + "------"); + if (wtLevel <= 0) { + wtLevel = 0.0; + } else if (wtLevel >= 100) { + wtLevel = 100.0; + } + DecimalFormat df = new DecimalFormat("0.0"); + String strWtLevel = df.format(wtLevel); + // 更新device_install数据 + deviceInstallService.updateLastValueByOther(addr, strWtLevel, "压变", buildingId); + nowDataService.saveNowHistoryData2(addr, "压变", strWtLevel, "waterLevel", buildingId); + log.info("压变号:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); + nowDataService.proWaterLevel(dateStr, buildingId, addr); //楼栋水位 + log.info("------保存每栋楼小时水位情况" + dateStr + "------"); + result = strWtLevel; + } + return result; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/StatusCheckStrategy.java b/user-service/src/main/java/com/mh/user/strategy/StatusCheckStrategy.java new file mode 100644 index 0000000..701167c --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/StatusCheckStrategy.java @@ -0,0 +1,126 @@ +package com.mh.user.strategy; + +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.entity.NowPublicDataEntity; +import com.mh.user.service.*; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 电表运行策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class StatusCheckStrategy implements DeviceStrategy { + + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + + private static class SingletonHolder { + private static final StatusCheckStrategy INSTANCE = new StatusCheckStrategy(); + } + + private StatusCheckStrategy() { + // 防止外部直接实例化 + } + + public static StatusCheckStrategy getInstance() { + return StatusCheckStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + // 0代表前面补充0,12代表长度为12,d代表参数为正数型.12位通讯地址,以0补位 + str = String.format("%012d", Long.parseLong(deviceAddr)); + // 转换位置 + str = ExchangeStringUtil.changePosition(str); + // 拼接功能码 + str = "68" + str + "680102"; + String strData = "25C0"; + // 加33操作 + str = str + ExchangeStringUtil.addThree(strData); + // 检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str); + str = "FEFEFE" + str + checkSum + "16"; + + } catch (Exception e) { + log.error("生成状态检测指令出错!" + str, e); + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + if (dataStr.length() == 30) { + //检验报文 + String checkStr = dataStr.substring(0, dataStr.length() - 4); //减去校验码 + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + //返回的校验码与重新生成的校验码进行校验 + if (checkNum.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4, dataStr.length() - 2))) { + return Constant.FAIL; + } + //表号,12位 + String meterId = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) + + checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); + meterId = meterId.replaceAll("^0*", ""); + //数值 + String data = checkStr.substring(24, 26); + data = ExchangeStringUtil.cutThree(data); + String strStatus = ExchangeStringUtil.hexString2binaryString(data); + strStatus = String.format("%08d", Long.parseLong(strStatus)); + String backWater; + if (strStatus.charAt(7) == '1') {//回水 + backWater = "运行"; + } else { + backWater = "不运行"; + } + String hotPump; + if (strStatus.charAt(6) == '1') {//热泵 + hotPump = "运行"; + } else { + hotPump = "不运行"; + } + String upWater; + if (strStatus.charAt(5) == '1') {//上水或者补水 + upWater = "运行"; + } else { + upWater = "不运行"; + } + String useWater; + if (strStatus.charAt(4) == '1') {//用水或者供水 + useWater = "运行"; + } else { + useWater = "不运行"; + } + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setUseWater(useWater); + publicData.setUpWater(upWater); + publicData.setBackWater(backWater); + publicData.setBuildingId(buildingId); + try { + //通过状态检测保存热泵状态 + nowDataService.saveNowHistoryData2(meterId, "状态检测", hotPump, "runState", buildingId); + nowPublicDataService.saveNowHistoryPublicData(publicData); + nowDataService.proPumpMinutes(buildingId, "1", hotPump); //如果只有一台热泵,pumpId为1 + log.info("状态ID:" + meterId + ",回水:" + backWater + ",补水:" + upWater + ",供水:" + useWater + ",热泵:" + hotPump + ",保存数据成功!楼栋:" + buildingName); + } catch (Exception e) { + log.error("解析状态检测异常==>", e); + } + return Constant.SUCCESS; + } + return Constant.FAIL; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/TempControlStrategy.java b/user-service/src/main/java/com/mh/user/strategy/TempControlStrategy.java new file mode 100644 index 0000000..3f7431e --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/TempControlStrategy.java @@ -0,0 +1,129 @@ +package com.mh.user.strategy; + +import com.alibaba.fastjson2.JSON; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.entity.NowPublicDataEntity; +import com.mh.user.service.BuildingService; +import com.mh.user.service.NowDataService; +import com.mh.user.service.NowPublicDataService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 温度控制器策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class TempControlStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + + BuildingService buildingService = context.getBean(BuildingService.class); + + + + private static class SingletonHolder { + private static final TempControlStrategy INSTANCE = new TempControlStrategy(); + } + + private TempControlStrategy() { + // 防止外部直接实例化 + } + + public static TempControlStrategy getInstance() { + return TempControlStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); //以0补位 +// if(registerAddr.equals("")){ +// str=str+"0300000002"; +// }else if(registerAddr.equals("")){ +// str=str+"0300000002"; +// } + str = str + "0300000002"; + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } catch (Exception e) { + log.error("生成温控指令出错!" + str, e); + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String result = Constant.FAIL; + String checkStr = dataStr.substring(0, dataStr.length() - 4);// 检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码 + if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + log.info("温度变送器报文检验失败: " + dataStr); + return result; + } + //log.info("温度变送器报文检验成功: " + receiveData); + String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + //log.info("温度变送器:" + addr); + String data = ""; + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读 + Map map = new HashMap<>(); + String L1 = checkStr.substring(6, 10); //1路 + map.put("1", String.valueOf(ExchangeStringUtil.parseHex4(L1) / 10)); + String L2 = checkStr.substring(10, 14); //2路 + map.put("2", String.valueOf(ExchangeStringUtil.parseHex4(L2) / 10)); + String L3 = checkStr.substring(14, 18); //3路 + map.put("3", String.valueOf(ExchangeStringUtil.parseHex4(L3) / 10)); + String L4 = checkStr.substring(18, 22); //4路 + map.put("4", String.valueOf(ExchangeStringUtil.parseHex4(L4) / 10)); + String L5 = checkStr.substring(22, 26); //5路 + map.put("5", String.valueOf(ExchangeStringUtil.parseHex4(L5) / 10)); + String L6 = checkStr.substring(26, 30); //6路 + map.put("6", String.valueOf(ExchangeStringUtil.parseHex4(L6) / 10)); + String L7 = checkStr.substring(30, 34); //7路 + map.put("7", String.valueOf(ExchangeStringUtil.parseHex4(L7) / 10)); + String L8 = checkStr.substring(34, 38); //8路 + map.put("8", String.valueOf(ExchangeStringUtil.parseHex4(L8) / 10)); + + int count = buildingService.selectPumpCount(buildingId); //楼栋热泵数 + if (count > 0) { + for (Map.Entry entry : map.entrySet()) { + addr = entry.getKey(); + data = entry.getValue(); + if (addr != null && Integer.parseInt(addr) <= count) { + nowDataService.saveNowHistoryData3(addr, "温度变送器", data, "waterTemp", buildingId); + nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存时间点温度 + } + } + log.info("温度变送器:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); + String avgTemp = nowDataService.selectAve(buildingId); + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + publicData.setUseWaterTemp(avgTemp); + publicData.setBackWaterTemp(avgTemp); + nowPublicDataService.saveNowHistoryPublicData(publicData); + result = JSON.toJSONString(map); //map转json字符串 + } + } + return result; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/TempTransStrategy.java b/user-service/src/main/java/com/mh/user/strategy/TempTransStrategy.java new file mode 100644 index 0000000..e1b29f3 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/TempTransStrategy.java @@ -0,0 +1,120 @@ +package com.mh.user.strategy; + +import com.alibaba.fastjson2.JSON; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.entity.NowPublicDataEntity; +import com.mh.user.service.BuildingService; +import com.mh.user.service.NowDataService; +import com.mh.user.service.NowPublicDataService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 压力变送器策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class TempTransStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + BuildingService buildingService = context.getBean(BuildingService.class); + + private static class SingletonHolder { + private static final TempTransStrategy INSTANCE = new TempTransStrategy(); + } + + private TempTransStrategy() { + // 防止外部直接实例化 + } + + public static TempTransStrategy getInstance() { + return TempTransStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); //以0补位 + str = str + "0300280008"; //读8路温度 + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } catch (Exception e) { + log.info("生成多路温度变送器指令出错!" + str, e); + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String result = Constant.FAIL; + String checkStr = dataStr.substring(0, dataStr.length() - 4);// 检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码 + if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + log.info("温度变送器报文检验失败: " + dataStr); + return result; + } + //log.info("温度变送器报文检验成功: " + receiveData); + String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + //log.info("温度变送器:" + addr); + String data = ""; + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读 + Map map = new HashMap<>(); + String L1 = checkStr.substring(6, 10); //1路 + map.put("1", String.valueOf(ExchangeStringUtil.parseHex4(L1) / 10)); + String L2 = checkStr.substring(10, 14); //2路 + map.put("2", String.valueOf(ExchangeStringUtil.parseHex4(L2) / 10)); + String L3 = checkStr.substring(14, 18); //3路 + map.put("3", String.valueOf(ExchangeStringUtil.parseHex4(L3) / 10)); + String L4 = checkStr.substring(18, 22); //4路 + map.put("4", String.valueOf(ExchangeStringUtil.parseHex4(L4) / 10)); + String L5 = checkStr.substring(22, 26); //5路 + map.put("5", String.valueOf(ExchangeStringUtil.parseHex4(L5) / 10)); + String L6 = checkStr.substring(26, 30); //6路 + map.put("6", String.valueOf(ExchangeStringUtil.parseHex4(L6) / 10)); + String L7 = checkStr.substring(30, 34); //7路 + map.put("7", String.valueOf(ExchangeStringUtil.parseHex4(L7) / 10)); + String L8 = checkStr.substring(34, 38); //8路 + map.put("8", String.valueOf(ExchangeStringUtil.parseHex4(L8) / 10)); + + int count = buildingService.selectPumpCount(buildingId); //楼栋热泵数 + if (count > 0) { + for (Map.Entry entry : map.entrySet()) { + addr = entry.getKey(); + data = entry.getValue(); + if (addr != null && Integer.parseInt(addr) <= count) { + nowDataService.saveNowHistoryData3(addr, "温度变送器", data, "waterTemp", buildingId); + nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存时间点温度 + } + } + log.info("温度变送器:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); + String avgTemp = nowDataService.selectAve(buildingId); + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + publicData.setUseWaterTemp(avgTemp); + publicData.setBackWaterTemp(avgTemp); + nowPublicDataService.saveNowHistoryPublicData(publicData); + result = JSON.toJSONString(map); //map转json字符串 + } + } + return result; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/TimeControlStrategy.java b/user-service/src/main/java/com/mh/user/strategy/TimeControlStrategy.java new file mode 100644 index 0000000..eebe28c --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/TimeControlStrategy.java @@ -0,0 +1,120 @@ +package com.mh.user.strategy; + +import com.mh.common.utils.StringUtils; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.service.NowDataService; +import com.mh.user.service.NowPublicDataService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 时间控制器策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class TimeControlStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + + private static class SingletonHolder { + private static final TimeControlStrategy INSTANCE = new TimeControlStrategy(); + } + + private TimeControlStrategy() { + // 防止外部直接实例化 + } + + public static TimeControlStrategy getInstance() { + return TimeControlStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String funCode = deviceCodeParamEntity.getFunCode(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String dataValue = deviceCodeParamEntity.getDataValue(); + String param = deviceCodeParamEntity.getParam(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); //以0补位 + try { + if (!StringUtils.isBlank(funCode)) { + registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4); //寄存器地址 + funCode = ExchangeStringUtil.addZeroForNum(funCode, 2); // 功能码 + + if (funCode.equals("03")) { //功能码,读 + if (param.equals("checkTime")) { + // 读取时间:0A 03 00 00 00 03 04 B0 + str = str + "03" + registerAddr + "0003"; + } else { + str = str + "03" + registerAddr + "0004"; + } + } else if (funCode.equals("10")) {//写 + if (!dataValue.equals("") && !param.equals("checkTime")) { + str = str + "10" + registerAddr + "000408" + dataValue; + } else { + // 校验时间:0A 10 00 00 00 03 06 00 24 01 10 08 59 48 CF + // 0A 10 00 00 00 03 06 00 24 01 10 09 40 8B 95 + str = str + "10" + registerAddr + "00030600" + dataValue.substring(2); + } + } + } + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } catch (Exception e) { + log.error("生成时控指令出错!" + str, e); + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String result = Constant.FAIL; + String checkStr = dataStr.substring(0, dataStr.length() - 4); + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码 + if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + return result; + } + log.info("时控报文检验成功: " + dataStr); + //地址 + String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2)); + log.info("时控号: " + addr); + String data = ""; + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读 + int rec = dataStr.length(); + + if (rec == 26) { //读时间设置值 + data = checkStr.substring(6, rec - 4); + String curTimeBegin1 = data.substring(0, 2) + ":" + data.substring(2, 4); + String curTimeEnd1 = data.substring(4, 6) + ":" + data.substring(6, 8); + String curTimeBegin2 = data.substring(8, 10) + ":" + data.substring(10, 12); + String curTimeEnd2 = data.substring(12, 14) + ":" + data.substring(14, 16); + + } else if (rec == 22) { //读校对时间 + data = checkStr.substring(8, rec - 4); + String strDate = "20" + data.substring(0, 2) + "-" + data.substring(2, 4) + "-" + data.substring(4, 6); //拼接日期 + String strTime = data.substring(6, 8) + ":" + data.substring(8, 10); //拼接时间 + } + result = data; + } else if (checkStr.substring(2, 4).equalsIgnoreCase("05") || checkStr.substring(2, 4).equalsIgnoreCase("10")) { + log.info("时间: " + dateStr + ",时控ID: " + addr + ",操作成功! "); + return Constant.SUCCESS; + } + return result; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/WaterLevelSwitchStrategy.java b/user-service/src/main/java/com/mh/user/strategy/WaterLevelSwitchStrategy.java new file mode 100644 index 0000000..afaceac --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/WaterLevelSwitchStrategy.java @@ -0,0 +1,531 @@ +package com.mh.user.strategy; + +import com.alibaba.fastjson2.JSON; +import com.mh.common.utils.StringUtils; +import com.mh.user.constants.Constant; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.entity.NowPublicDataEntity; +import com.mh.user.entity.SysParamEntity; +import com.mh.user.service.BuildingService; +import com.mh.user.service.NowDataService; +import com.mh.user.service.NowPublicDataService; +import com.mh.user.service.SysParamService; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 水位开关策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class WaterLevelSwitchStrategy implements DeviceStrategy { + + + // 调用service + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + NowDataService nowDataService = context.getBean(NowDataService.class); + + NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); + + SysParamService sysParamService = context.getBean(SysParamService.class); + + BuildingService buildingService = context.getBean(BuildingService.class); + + private static class SingletonHolder { + private static final WaterLevelSwitchStrategy INSTANCE = new WaterLevelSwitchStrategy(); + } + + private WaterLevelSwitchStrategy() { + // 防止外部直接实例化 + } + + public static WaterLevelSwitchStrategy getInstance() { + return WaterLevelSwitchStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String funCode = deviceCodeParamEntity.getFunCode(); + String registerAddr = deviceCodeParamEntity.getRegisterAddr(); + String dataValue = deviceCodeParamEntity.getDataValue(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + if (StringUtils.isBlank(brand) || Constant.BRAND_ZHONG_KAI.equals(brand)) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + if (StringUtils.isBlank(funCode) || funCode.equals("17")) { //读 + str = "33" + str + "1700000000"; //旧版继电器 + } else if (funCode.equals("12")) {//写 + if (dataValue != null && !dataValue.equals("")) { + //0001(90%) 0002(80%) 0003(70%)... + if (dataValue.equals("100%")) { + registerAddr = "1300000000"; //全开 + } else if (dataValue.equals("90%")) { + registerAddr = "1200000001"; + } else if (dataValue.equals("80%")) { + registerAddr = "1200000002"; + } else if (dataValue.equals("70%")) { + registerAddr = "1200000003"; + } else if (dataValue.equals("60%")) { + registerAddr = "1200000004"; + } else if (dataValue.equals("50%")) { + registerAddr = "1200000005"; + } else if (dataValue.equals("40%")) { + registerAddr = "1200000006"; + } + str = "33" + str + registerAddr; //示例:33011200000001 + } + } else if (funCode.equals("13")) {//写 + str = "33" + str + "1300000000"; //全开 + } else { + str = "33" + str + "1400000000"; //全合 + } + // 检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str); + str = str + checkSum; + + } else if (Constant.BRAND_YUAN_XIANG.equals(brand)) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + if (StringUtils.isBlank(funCode) || funCode.equals("03")) {//读 + if (registerAddr.equalsIgnoreCase("0018")) { //读全部位置 + str = str + "0300180008"; + } else if (registerAddr.equalsIgnoreCase("0010")) { //读全部DI + str = str + "0300100008"; + } + } else if (funCode.equals("06")) { // 写 + if (!StringUtils.isBlank(dataValue)) { + if (dataValue.equals("100%")) { + registerAddr = "10001800081000000000000000000000000000000000"; //全开 + } else if (dataValue.equals("90%")) { + registerAddr = "0600180001"; + } else if (dataValue.equals("80%")) { + registerAddr = "0600190001"; + } else if (dataValue.equals("70%")) { + registerAddr = "06001A0001"; + } else if (dataValue.equals("60%")) { + registerAddr = "06001B0001"; + } else if (dataValue.equals("50%")) { + registerAddr = "06001C0001"; + } else if (dataValue.equals("40%")) { + registerAddr = "06001D0001"; + } + //0018(90%) 0019(80%) 001A(70%)... + str = str + registerAddr; //示例:010600180001 + } + } else {//写 + if (dataValue.equals("0000")) { + str = str + "10001800081000000000000000000000000000000000"; //全开 + } else { + str = str + "10001800081000010001000100010001000100010001"; //全合 + } + } + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } else if (Constant.BRAND_DING_WEI.equals(brand)) { + str = String.format("%012d", Long.parseLong(deviceAddr)); + //转换位置 + str = ExchangeStringUtil.changePosition(str); //表号 + String strData = ""; + if (funCode.equals("0407")) {//写 + str = "68" + str + "680407"; + String mark = "25C0"; //C025交换位置 + String strData1 = "00000000"; //命令带密码4字节,权限密码默认为00000000 + String strData2 = ""; + if (dataValue.equals("100%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00000000"); + } else if (dataValue.equals("90%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00000001"); + } else if (dataValue.equals("85%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00000011"); + } else if (dataValue.equals("80%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00000111"); + } else if (dataValue.equals("75%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00001111"); + } else if (dataValue.equals("70%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00011111"); + } else if (dataValue.equals("65%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00111111"); + } else if (dataValue.equals("60%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("01111111"); + } else if (dataValue.equals("50%")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("11111111"); + } else if (dataValue.equals("自动")) { + strData2 = ExchangeStringUtil.parseByte2HexStr("00100110"); + } + strData = mark + strData1 + strData2; + } else if (funCode.equals("0102")) { //读 + str = "68" + str + "680102"; + strData = "25C0"; //标志 + } + strData = ExchangeStringUtil.addThree(strData); //加33 + str = str + strData; + //检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str);//校验 + str = "FEFEFE" + str + checkSum + "16"; + } + } catch (Exception e) { + if (registerAddr.equals("0010")) { + log.error("生成热泵状态指令出错!" + str, e); + } else { + log.error("生成水位开关指令出错!" + str, e); + } + } + } + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + SysParamEntity sysParamEntity = sysParamService.selectSysParam(); + String customName = sysParamEntity.getCustomName(); + if (StringUtils.isBlank(registerAddr) || Constant.REG_ADDR_0018.equals(registerAddr) || Constant.REG_ADDR_0017.equals(registerAddr)) { + return analysisRelayOrder485(dateStr, dataStr, registerAddr, brand, buildingId, buildingName, customName); + } else if (Constant.REG_ADDR_0010.equals(registerAddr) && !StringUtils.isBlank(registerAddr)){ + return handleWaterSwitch(dateStr, dataStr, registerAddr, brand, buildingId, buildingName); + } + return Constant.FAIL; + } + + private String handleWaterSwitch(String dateStr, String dataStr, String registerAddr, String brand, + String buildingId, String buildingName) { + log.info("进入水位开关,地址==>{}", registerAddr); + SysParamEntity sysParamEntity = sysParamService.selectSysParam(); + String customName = sysParamEntity.getCustomName(); + if (!StringUtils.isBlank(customName)) { + if (customName.contains(Constant.CUSTOM_NAME_HUAXIA) + || customName.contains(Constant.CUSTOM_NAME_GUANGSHANG)) { + return analysisRelayOrder485(dateStr, dataStr,registerAddr,brand,buildingId, buildingName, customName); + } else { + return analysisPumpStateOrder(dateStr, dataStr, registerAddr, brand, buildingId, buildingName); + } + } else { + return analysisPumpStateOrder(dateStr, dataStr, registerAddr, brand, buildingId, buildingName); + } + } + + // 热泵状态处理(水位开关),长度42,128 + public String analysisPumpStateOrder(final String dateStr, final String receiveData, final String registerAddr, final String brand, String buildingId, String buildingName) { + String result = Constant.FAIL; + String l1 = ""; + String l2 = ""; + String l3 = ""; + String l4 = ""; + String l5 = ""; + String l6 = ""; + String l7 = ""; + String l8 = ""; + String runState = ""; + String addr = ""; + Map map = new HashMap(); + if (StringUtils.isBlank(brand) || brand.equals("顶威")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4); //检验报文减,去校验码 + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) { + //表号,12位 + addr = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) + + checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); + addr = addr.replaceAll("^0*", ""); + String data = checkStr.substring(24, 26); //截取数值 + data = ExchangeStringUtil.cutThree(data); + String strStatus = ExchangeStringUtil.hexString2binaryString(data); + strStatus = String.format("%08d", Long.parseLong(strStatus)); + if (strStatus.charAt(7) == '1') { + l1 = "1"; + } else { + l1 = "0"; + } + if (strStatus.charAt(6) == '1') { + l2 = "1"; + } else { + l2 = "0"; + } + if (strStatus.charAt(5) == '1') { + l3 = "1"; + } else { + l3 = "0"; + } + if (strStatus.charAt(4) == '1') { + l4 = "1"; + } else { + l4 = "0"; + } + if (strStatus.charAt(3) == '1') { + l5 = "1"; + } else { + l5 = "0"; + } + if (strStatus.charAt(2) == '1') { + l6 = "1"; + } else { + l6 = "0"; + } + if (strStatus.charAt(1) == '1') { + l7 = "1"; + } else { + l7 = "0"; + } + if (strStatus.charAt(0) == '1') { + l8 = "1"; + } else { + l8 = "0"; + } + } + } else if (brand.equals("中凯")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4); //检验报文,减去校验码 + addr = ExchangeStringUtil.hexToDec(checkStr.substring(2, 4)); + l1 = checkStr.substring(4, 6); + l2 = checkStr.substring(20, 22); + l3 = checkStr.substring(36, 38); + l4 = checkStr.substring(52, 54); + l5 = checkStr.substring(68, 70); + l6 = checkStr.substring(84, 86); + l7 = checkStr.substring(100, 102); + l8 = checkStr.substring(116, 118); + } else if (brand.equals("远向")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4);// 检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr); + if (checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { + addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + l1 = checkStr.substring(6, 10); + l2 = checkStr.substring(10, 14); + l3 = checkStr.substring(14, 18); + l4 = checkStr.substring(18, 22); + l5 = checkStr.substring(22, 26); + l6 = checkStr.substring(26, 30); + l7 = checkStr.substring(30, 34); + l8 = checkStr.substring(34, 38); + } else { + log.info("热泵状态报文检验失败: " + receiveData); + } + } + if (l1.equals("12") || l1.equals("0001")) { //正常是0001 + map.put("1", "运行"); + } else { + map.put("1", "不运行"); + } + if (l2.equals("12") || l2.equals("0001")) { + map.put("2", "运行"); + } else { + map.put("2", "不运行"); + } + if (l3.equals("12") || l3.equals("0001")) { + map.put("3", "运行"); + } else { + map.put("3", "不运行"); + } + if (l4.equals("12") || l4.equals("0001")) { + map.put("4", "运行"); + } else { + map.put("4", "不运行"); + } + if (l5.equals("12") || l5.equals("0001")) { + map.put("5", "运行"); + } else { + map.put("5", "不运行"); + } + if (l6.equals("12") || l6.equals("0001")) { + map.put("6", "运行"); + } else { + map.put("6", "不运行"); + } + if (l7.equals("12") || l7.equals("0001")) { + map.put("7", "运行"); + } else { + map.put("7", "不运行"); + } + if (l8.equals("12") || l8.equals("0001")) { + map.put("8", "运行"); + } else { + map.put("8", "不运行"); + } + int count = buildingService.selectPumpCount(buildingId); //楼栋热泵数 + if (count > 0) { + for (Map.Entry entry : map.entrySet()) { + addr = entry.getKey(); //获取Key值作为热泵ID + runState = entry.getValue(); + if (addr != null && Integer.parseInt(addr) <= count) { + nowDataService.saveNowHistoryData3(addr, "热泵状态", runState, "runState", buildingId); + nowDataService.proPumpMinutes(buildingId, addr, runState); //计算热泵运行时长 + nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存时间点温度 + log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + runState); + } + } + log.info("热泵状态号:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); + result = JSON.toJSONString(map); //map转json字符串 + } + return result; + } + + // 水位开关,长度42,128 + public String analysisRelayOrder485(final String dateStr,final String receiveData, final String registerAddr, final String brand, String buildingId, String buildingName, String customName) { +// threadPoolService.execute(() -> { + String l1 = ""; + String l2 = ""; + String l3 = ""; + String l4 = ""; + String l5 = ""; + String l6 = ""; + String l7 = ""; + String l8 = ""; + String waterLevelSet = ""; + String addr = ""; + if (brand == null || brand.equals("") || brand.equals("中凯")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4); //减去校验码 + addr = ExchangeStringUtil.hexToDec(checkStr.substring(2, 4)); + if (registerAddr != null && !registerAddr.equals("")) { + if (registerAddr.equalsIgnoreCase("0017")) { //中凯拿功能码作为寄存器地址用 + l1 = checkStr.substring(4, 6); + l2 = checkStr.substring(20, 22); + l3 = checkStr.substring(36, 38); + l4 = checkStr.substring(52, 54); + l5 = checkStr.substring(68, 70); + l6 = checkStr.substring(84, 86); + l7 = checkStr.substring(100, 102); + l8 = checkStr.substring(116, 118); + } else if (registerAddr.equals("0012")) { + log.info("时间:" + dateStr + ",水位开关ID:" + addr + ",操作成功! "); + } + } + } else if (brand.equals("远向")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4);// 检验报文 + String checkWord = ExchangeStringUtil.getStrCRC16(checkStr); + if (checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { + addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + if (checkStr.substring(2, 4).equals("03")) { + if (registerAddr != null && !registerAddr.equals("")) { + if (registerAddr.equals("0018")){ + l1 = checkStr.substring(6, 10); + l2 = checkStr.substring(10, 14); + l3 = checkStr.substring(14, 18); + l4 = checkStr.substring(18, 22); + l5 = checkStr.substring(22, 26); + l6 = checkStr.substring(26, 30); + l7 = checkStr.substring(30, 34); + l8 = checkStr.substring(34, 38); + } + } + } else if (checkStr.substring(2, 4).equals("06") || checkStr.substring(2, 4).equals("04")) { + log.info("时间:" + dateStr + ",水位开关ID:" + addr + ",操作成功! "); + } + } else { + log.info("水位开关报文检验失败: " + receiveData); + } + } else if (brand.equals("顶威")) { + String checkStr = receiveData.substring(0, receiveData.length() - 4); //减去校验码 + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) { + //表号,12位 + String meterId = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) + + checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); + meterId = String.format("%012d", Long.parseLong(meterId)); + if (registerAddr != null && !registerAddr.equals("")) { + if (registerAddr.equals("0102")) { + String data = receiveData.substring(26, 28); + data = ExchangeStringUtil.cutThree(data); + data = ExchangeStringUtil.addZeroForNum(data, 2); + if (data.equalsIgnoreCase("00")) {//全闭 + waterLevelSet = "100"; //100% + } else if (data.equalsIgnoreCase("01")) { + waterLevelSet = "90"; //90% + } else if (data.equalsIgnoreCase("03")) { + waterLevelSet = "85"; + } else if (data.equalsIgnoreCase("07")) { + waterLevelSet = "80"; + } else if (data.equalsIgnoreCase("0F")) { + waterLevelSet = "75"; + } else if (data.equalsIgnoreCase("1F")) { + waterLevelSet = "70"; + } else if (data.equalsIgnoreCase("3F")) { + waterLevelSet = "65"; + } else if (data.equalsIgnoreCase("7F")) { + waterLevelSet = "60"; + } else if (data.equalsIgnoreCase("FF")) { //全开 + waterLevelSet = "50"; + } else if (data.equalsIgnoreCase("24")) { + waterLevelSet = "自动"; + } + nowDataService.saveNowHistoryData2(meterId, "水位开关", waterLevelSet, "levelSet", buildingId); + log.info("水位开关号:" + meterId + ",保存数据库成功!楼栋名称:" + buildingName); + } else if (registerAddr.equalsIgnoreCase("0407")) { + log.info("时间: " + dateStr + ",继电器ID: " + meterId + ",操作成功! "); + } + } + } else { + log.info("水位开关报文检验失败: " + receiveData); + } + } + if (registerAddr != null && !registerAddr.equals("")) { + if (registerAddr.equals("0017") || registerAddr.equals("0018")) { + if (l1.equals("12") || l1.equals("0001")) { + waterLevelSet = "90"; + } else if (l2.equals("12") || l2.equals("0001")) { + waterLevelSet = "80"; + } else if (l3.equals("12") || l3.equals("0001")) { + waterLevelSet = "70"; + } else if (l4.equals("12") || l4.equals("0001")) { + waterLevelSet = "60"; + } else if (l5.equals("12") || l5.equals("0001")) { + waterLevelSet = "50"; + } else if (l6.equals("12") || l6.equals("0001")) { + waterLevelSet = "40"; + } + //全开或者全关 + if (l1.equals("12") && l2.equals("12") && l3.equals("12") && l4.equals("12") && l5.equals("12") && l6.equals("12")) { + waterLevelSet = "40"; + } else if (l1.equals("11") && l2.equals("11") && l3.equals("11") && l4.equals("11") && l5.equals("11") && l6.equals("11")) { + waterLevelSet = "100"; + } else if (l1.equals("0001") && l2.equals("0001") && l3.equals("0001") && l4.equals("0001") && l5.equals("0001") && l6.equals("0001")) { + waterLevelSet = "40"; + } else if (l1.equals("0000") && l2.equals("0000") && l3.equals("0000") && l4.equals("0000") && l5.equals("0000") && l6.equals("0000")) { + waterLevelSet = "100"; + } + nowDataService.saveNowHistoryData2(addr, "水位开关", waterLevelSet, "levelSet", buildingId); + log.info("水位开关保存数据库成功!楼栋名称:" + buildingName); + return waterLevelSet; + } else if (registerAddr.equals("0010")) { + NowPublicDataEntity publicData = new NowPublicDataEntity(); + publicData.setBuildingId(buildingId); + if (customName.contains(Constant.CUSTOM_NAME_GUANGSHANG)) { + if (l8.equals("0001")) { //l8路,0000表示有输入,0001表示无输入 + publicData.setUseWater("运行"); //供水 + publicData.setBackWater("运行");//回水 + } else { + publicData.setUseWater("不运行"); + publicData.setBackWater("不运行"); + } + log.info("-----------------供水/回水状态:" + l8 + "-----------------"); + } else { + if (l1.equals("0001")) { //l路,0000表示有输入,0001表示无输入 + publicData.setUseWater("运行"); //供水 + publicData.setBackWater("运行");//回水 + } else { + publicData.setUseWater("不运行"); + publicData.setBackWater("不运行"); + } + log.info("-----------------供水/回水状态:" + l1 + "-----------------"); + if (l2.equals("0001")) { //2路 //补水 + publicData.setUpWater("运行"); + } else { + publicData.setUpWater("不运行"); + } + log.info("-----------------补水状态:" + l2 + "-----------------"); + } + nowPublicDataService.saveNowHistoryPublicData(publicData); + log.info("-----------------状态保存数据库成功!楼栋名称:" + buildingName + "-----------------"); + } + } + return Constant.FAIL; + } +} diff --git a/user-service/src/main/java/com/mh/user/strategy/WtMeterStrategy.java b/user-service/src/main/java/com/mh/user/strategy/WtMeterStrategy.java new file mode 100644 index 0000000..ac79a16 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/strategy/WtMeterStrategy.java @@ -0,0 +1,133 @@ +package com.mh.user.strategy; + +import com.mh.common.utils.StringUtils; +import com.mh.user.entity.DataResultEntity; +import com.mh.user.entity.DeviceCodeParamEntity; +import com.mh.user.service.DataResultService; +import com.mh.user.utils.CRC16; +import com.mh.user.utils.ExchangeStringUtil; +import com.mh.user.utils.SpringBeanUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.Date; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 电表运行策略 + * @date 2024-03-18 09:51:17 + */ +@Slf4j +public class WtMeterStrategy implements DeviceStrategy { + + ApplicationContext context = SpringBeanUtil.getApplicationContext(); + + DataResultService dataResultService = context.getBean(DataResultService.class); + + private static class SingletonHolder { + private static final WtMeterStrategy INSTANCE = new WtMeterStrategy(); + } + + private WtMeterStrategy() { + // 防止外部直接实例化 + } + + public static WtMeterStrategy getInstance() { + return WtMeterStrategy.SingletonHolder.INSTANCE; + } + + @Override + public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { + String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); + String brand = deviceCodeParamEntity.getBrand(); + String str = ""; + if (deviceAddr != null && deviceAddr.length() > 0) { + try { + if (StringUtils.isBlank(brand) || brand.equals("艾美柯")) { + // 0 代表前面补充0,14 代表长度为14,d 代表参数为正数型 + str = String.format("%014d", Long.parseLong(deviceAddr));//基表通讯号 + // 转换位置 + str = ExchangeStringUtil.changePosition(str); + // 拼接功能码 + str = "6810" + str + "0103901F00"; //水表读读数指令 + // 检验和 + String checkSum = ExchangeStringUtil.makeChecksum(str); + str = "FEFEFE" + str + checkSum + "16"; + } else if (brand.equals("脉冲")) { + str = ExchangeStringUtil.decToHex(deviceAddr); + str = ExchangeStringUtil.addZeroForNum(str, 2); + str = str + "0302020002";//读表累计值 + String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 + str = str + checkWord; + } + } catch (Exception e) { + e.printStackTrace(); + log.error("生成水表采集指令异常>>>>", e); + } + } + log.info("生成水表采集指令>>>>" + str); + return str.toUpperCase(); + } + + @Override + public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { + String data = ""; + String meterId = ""; + if (dataStr.length() == 44 || dataStr.length() == 70 || dataStr.length() == 72) { + String checkStr = dataStr.substring(0, dataStr.length() - 4);//减去校验码 + String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 + if (checkNum.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4, dataStr.length() - 2))) { + meterId = checkStr.substring(16, 18) + checkStr.substring(14, 16) + checkStr.substring(12, 14) + checkStr.substring(10, 12)// 表号 + + checkStr.substring(8, 10) + checkStr.substring(6, 8) + checkStr.substring(4, 6); + meterId = String.format("%014d", Long.parseLong(meterId)); + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < 4; i++) { + String data1 = checkStr.substring(36 - 2 * (i + 1), 36 - 2 * i); + stringBuilder.append(data1); + } + data = stringBuilder.toString(); + // 0 代表前面补充0,4 代表长度为4,d 代表参数为正数型 + data = String.format("%08d", Long.parseLong(data)); + data = data.substring(0, 6) + "." + data.substring(6, 8); + } else { + log.info("水表报文检验失败: " + dataStr); + } + } else if (dataStr.length() == 18) { + String checkStr = dataStr.substring(0, dataStr.length() - 4);//检验报文 + byte[] strOrder = ExchangeStringUtil.hexStrToBinaryStr(checkStr); + int checkNum = CRC16.CRC16_MODBUS(strOrder); + String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum)); + checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2); + String sValue = null; + if (checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { + meterId = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 + if (checkStr.substring(2, 4).equalsIgnoreCase("03")) { + data = String.valueOf(Integer.parseInt(ExchangeStringUtil.hexToDec(checkStr.substring(6, 14))) / 10); //读数 + } + } else { + log.info("水表报文检验失败: " + dataStr); + } + } + log.info("水表表号: " + meterId + ",水表读数:" + data); + try { + DataResultEntity dataResultEntity = new DataResultEntity(); + dataResultEntity.setDeviceAddr(meterId);//通讯编号 + dataResultEntity.setDeviceType("水表"); + dataResultEntity.setCurValue(Double.parseDouble(data)); //当前读数 + Date date = new Date(); + dataResultEntity.setCurDate(date); //当前日期 + dataResultEntity.setBuildingId(buildingId); + dataResultService.saveDataResult(dataResultEntity); + log.info("水表数据保存数据库成功!楼栋名称:" + buildingName); + } catch (Exception e) { + e.printStackTrace(); + log.error("水表数据保存数据库失败!楼栋名称:" + buildingName); + } + if (StringUtils.isBlank(data)) { + data = String.valueOf(Double.valueOf(data)); + } + return data; + } +}