This commit is contained in:
Timer
2026-01-29 17:06:01 +08:00
commit e90e11527d
158 changed files with 15057 additions and 0 deletions

View File

@ -0,0 +1,47 @@
package com.sipai;
import com.sipai.tools.DataSourceAspect;
import com.sipai.tools.DataSourceContextHolder;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//@SpringBootApplication
/**
* @SpringBootApplication 为
* @Configuration、@EnableAutoConfiguration、@ComponentScan 三个注解的组合
*/
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
@EnableTransactionManagement //开启事务功能
@EnableAsync//开启异步
@EnableScheduling
@MapperScan("src/main/resources/mybatis/mapper")
//@PropertySource("classpath:application-pro.yml")//yml里面指定pro失效只能在这强制指定
public class DataApplication {
static{
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(DataApplication.class);
app.setAllowBeanDefinitionOverriding(false); // 检查是否有此设置
app.run(args);
}
}

View File

@ -0,0 +1,18 @@
package com.sipai.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
private int maxPoints;
public int getMaxPoints() {
return maxPoints;
}
public void setMaxPoints(int maxPoints) {
this.maxPoints = maxPoints;
}
}

View File

@ -0,0 +1,38 @@
package com.sipai.config;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.stack.client.UaStackClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
public class MockOpcUaClient extends OpcUaClient {
public MockOpcUaClient(OpcUaClientConfig config) throws Exception {
super(config, (UaStackClient) Executors.newSingleThreadExecutor()); // 提供所有必需的参数
}
private static OpcUaClientConfig createMockConfig() {
return OpcUaClientConfig.builder()
.setEndpoint(null) // 模拟端点
.setApplicationName(LocalizedText.english("Mock OPC UA Client"))
.build();
}
public static MockOpcUaClient createMockClient() throws Exception {
return new MockOpcUaClient(createMockConfig());
}
@Override
public CompletableFuture<DataValue> readValue(double timeout, TimestampsToReturn timestamps, NodeId nodeId) {
DataValue dataValue = new DataValue(
new Variant(0), // 模拟值
StatusCode.GOOD,
null,
null
);
return CompletableFuture.completedFuture(dataValue);
}
}

View File

@ -0,0 +1,76 @@
package com.sipai.config;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class OpcUaConfig {
@Autowired
private OpcUaProperties properties;
@Bean
@ConditionalOnProperty(prefix = "opcua", name = "enabled", havingValue = "true")
public OpcUaClient opcUaClient() throws Exception {
return createClient(properties);
}
/*@Bean
public OpcUaClient opcUaClient(OpcUaProperties properties) throws Exception {
if (!properties.isEnabled()) {
// 如果 OPC UA 功能未启用,返回 null 或抛出自定义异常
return null; // 或者抛出一个自定义异常
}
return createClient(properties);
}*/
private OpcUaClient createClient(OpcUaProperties properties) throws Exception {
// 1. 发现端点
List<EndpointDescription> endpoints = DiscoveryClient
.getEndpoints(properties.getServerUrl())
.get();
// 2. 根据配置选择端点
EndpointDescription endpoint = endpoints.stream()
.filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
.findFirst()
.orElseThrow(() -> new Exception("未找到匿名访问端点"));
// 3. 创建身份认证提供者
IdentityProvider identityProvider;
if (properties.getUsername() != null && !properties.getUsername().isEmpty()) {
// 使用用户名/密码认证
identityProvider = new UsernameProvider(
properties.getUsername(),
properties.getPassword()
);
} else {
// 使用匿名认证
identityProvider = new AnonymousProvider();
}
// 4. 创建客户端配置
OpcUaClientConfig config = OpcUaClientConfig.builder()
.setEndpoint(endpoint)
.setRequestTimeout(UInteger.valueOf(5000))
.setIdentityProvider(identityProvider)
.build();
// 5. 创建并连接客户端
OpcUaClient client = OpcUaClient.create(config);
client.connect().get();
return client;
}
}

View File

@ -0,0 +1,66 @@
package com.sipai.config;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "opcua")
public class OpcUaProperties {
private String serverUrl;
private SecurityPolicy securityPolicy = SecurityPolicy.None;
private MessageSecurityMode securityMode = MessageSecurityMode.None;
private String username;
private String password;
private boolean enabled = false;//是否启用opc客户端
// Getters and Setters
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
public SecurityPolicy getSecurityPolicy() {
return securityPolicy;
}
public void setSecurityPolicy(SecurityPolicy securityPolicy) {
this.securityPolicy = securityPolicy;
}
public MessageSecurityMode getSecurityMode() {
return securityMode;
}
public void setSecurityMode(MessageSecurityMode securityMode) {
this.securityMode = securityMode;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@ -0,0 +1,75 @@
package com.sipai.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author : YYJ
* @CreateTime : 2021/9/13
* @Description :
**/
@Configuration
public class RedissonConfig {
private static String MODE_SINGLE = "single";
private static String MODE_CLUSTER = "cluster";
@Value("${spring.redis.mode}")
public String mode;
@Value("${spring.redis.cluster.nodes}")
public String cluster;
@Value("${spring.redis.password}")
public String password;
@Value("${spring.redis.host}")
public String host;
@Value("${spring.redis.port}")
public String port;
@Value("${spring.redis.timeout}")
public Integer timeout;
// @Value("${redis.database}")
// public String database;
@Bean
public RedissonClient redissonClient(){
RedissonClient redisson = null;
Config conf = new Config();
if(MODE_SINGLE.equals(mode)) {//单机
//单节点模式
SingleServerConfig singleServerConfig = conf.useSingleServer();
//设置连接地址redis://127.0.0.1:6379
singleServerConfig.setAddress("redis://" + host + ":" + port);
//设置连接密码
singleServerConfig.setPassword(password);
// singleServerConfig.setDatabase(Integer.valueOf(database));
}else if(MODE_CLUSTER.equals(mode)){//集群
String[] nodes = cluster.split(",");
for (int i = 0; i < nodes.length; i++) {
nodes[i] = "redis://" + nodes[i];
}
conf.useClusterServers()
.setScanInterval(2000)
.addNodeAddress(nodes)
.setTimeout(timeout)
.setPassword(password);
}
//使用json序列化方式
Codec codec = new JsonJacksonCodec();
conf.setCodec(codec);
redisson = Redisson.create(conf);
return redisson;
}
}

View File

@ -0,0 +1,20 @@
package com.sipai.config;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Component
public class StartupLogger {
@EventListener(ApplicationReadyEvent.class)
public void onStartup() throws UnknownHostException {
String ip = InetAddress.getLocalHost().getHostAddress();
String port = System.getProperty("server.port");//bat脚本传过来的端口
String url = ip + ":" + port;
System.out.println("Spring Boot 服务已启动完成!" + (url != null ? "开发环境" : url));
}
}

View File

@ -0,0 +1,80 @@
package com.sipai.config;
import org.springframework.beans.factory.annotation.Value;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 用于测试 - 南昌项目
* sj 2025-05-21
*/
public class UDPClient {
// @Value("${udp.server.port}")
// private static int serverPort;
public static void main(String[] args) {
// 管网监测设备采集
// 192.168.10.18:5006
// 223.84.61.83:5006
// String serverHost = "116.236.176.248";
// String serverHost = "127.0.0.1";
String serverHost = "223.84.61.83";
int serverPort = 5006;
//智能井盖
String hexString = "AB CD 00 4D 2A FB 25 07 20 12 00 01 A0 01 68 00 02 08 48 4B 33 35 2D 49 49 3B 56 31 2E 31 3B 56 31 2E 30 2E 30 36 00 00 00 00 00 00 00 00 04 01 C2 D2 00 00 04 02 40 E0 00 00 04 03 3F EC 7D AF 04 04 47 C3 50 00 04 05 47 C3 50 00 05 01 00 00 D3 0D 0A";
//流量计
// String hexString = "AB CD 00 71 56 03 25 07 08 09 15 01 0F 02 D8 00 FD 12 48 38 36 45 3B 31 2E 33 3B 31 2E 30 2E 33 35 20 20 20 20 20 00 00 00 00 00 00 00 00 01 01 DC 02 00 00 25 A8 00 00 01 02 00 00 00 00 03 00 00 00 01 03 DC 02 00 00 22 A8 00 00 04 01 3C A3 D7 0A 04 02 3D A3 D7 0A 04 03 41 A0 00 00 04 04 41 C4 7A E1 04 07 41 2C CC CD 04 08 3E 45 A1 CB 05 01 00 00 A2 0D 0A";
//液位计
// String hexString = "AB CD 00 B7 59 F7 25 07 08 09 05 03 05 01 6D 00 C0 06 48 4B 31 39 52 3B 33 2E 31 3B 31 2E 30 2E 30 30 00 00 00 00 00 00 00 00 00 00 00 00 04 01 42 E0 00 00 42 E0 00 00 42 E0 00 00 04 02 40 00 00 00 40 00 00 00 40 00 00 00 04 03 43 E8 80 00 43 E8 80 00 43 E8 80 00 04 04 3F C0 6A 32 40 0A 7D B4 3F C0 6A 32 04 05 40 69 D8 88 40 69 D8 88 40 69 D8 88 04 06 00 00 00 00 00 00 00 00 00 00 00 00 04 07 00 00 00 00 00 00 00 00 00 00 00 00 04 08 40 65 E3 55 40 65 D2 F2 40 65 B2 2E 04 09 3D DD 2F 00 3D DF 3B 60 3D E3 53 E0 04 0A 3D DD 2F 00 3D DF 3B 60 3D E3 53 E0 34 0D 0A";
//电导
// String hexString = "AB CD 00 A3 36 B1 25 06 21 18 15 08 0F 02 DC 00 D2 0D 48 38 36 45 3B 31 2E 33 3B 31 2E 30 2E 33 35 20 20 20 20 20 00 00 00 00 00 00 00 00 04 03 41 40 00 00 41 40 00 00 41 40 00 00 41 40 00 00 41 40 00 00 41 40 00 00 41 40 00 00 41 40 00 00 04 07 00 00 00 00 3A 83 12 6F 3A 83 12 6F 3A 83 12 6F 3A 83 12 6F 3A 83 12 6F 3A 83 12 6F 3A 83 12 6F 04 08 41 C8 CC CD 41 CA 66 66 41 CB 33 33 41 CC CC CD 41 D0 CC CD 41 D3 33 33 41 D4 CC CD 41 D5 99 9A 05 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A1 0D 0A";
//雨量计
// String hexString = "AB CD 00 8B 3A 99 25 06 21 13 33 02 01 04 64 00 A5 15 48 38 31 45 2D 3B 31 2E 34 3B 35 2E 30 2E 30 34 20 20 20 20 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00 00 00 00 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00 01 05 00 00 00 00 00 00 00 00 00 00 00 00 04 01 43 37 66 66 43 37 66 66 04 02 00 00 00 00 00 00 00 00 04 04 40 E8 80 00 40 F0 00 00 04 05 00 00 00 00 00 00 00 00 EE 0D 0A";
//内涝‘
// String hexString = "AB CD 00 6A 3E 81 25 06 21 13 33 01 01 05 6A 00 05 19 56 38 38 20 53 6D 61 72 74 20 20 20 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00 02 03 01 02 04 01 02 09 00 02 0A 00 02 0B 00 04 01 00 00 00 00 04 02 00 00 00 00 04 0D 00 00 00 00 01 0E 00 00 00 00 00 00 00 00 70 0D 0A";
hexString = hexString.replaceAll("\\s+", ""); // Remove all whitespace
byte[] data = hexStringToByteArray(hexString);
try (DatagramSocket socket = new DatagramSocket()) {
InetAddress serverAddress = InetAddress.getByName(serverHost);
// 发送数据包
DatagramPacket packet = new DatagramPacket(
data, data.length, serverAddress, serverPort);
socket.send(packet);
System.out.println("已发送数据包到服务器");
// 接收响应
byte[] buffer = new byte[1024];
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
String responseStr = new String(
response.getData(), 0, response.getLength());
System.out.println("服务器响应: " + responseStr);
} catch (IOException e) {
e.printStackTrace();
}
}
// 十六进制字符串转字节数组的方法
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}

View File

@ -0,0 +1,135 @@
package com.sipai.config;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 用于测试 - 南昌项目
* 修改为轮询txt文件并发送内容
* sj 2025-05-21
* 修改为仅轮询一次
*/
public class UDPFilePollingClient {
private static final String SERVER_HOST = "223.84.61.83"; // 默认本地
private static final int SERVER_PORT = 5006;
private static final String WATCH_DIRECTORY = "D:\\data_logs\\yewei"; // 监控当前目录
private static final Set<Path> processedFiles = Collections.synchronizedSet(new HashSet<>());
public static void main(String[] args) {
System.out.println("启动UDP文件轮询服务(单次运行),监控目录: " + WATCH_DIRECTORY);
pollAndProcessFiles();
System.out.println("文件轮询处理完成");
}
private static void pollAndProcessFiles() {
try {
List<Path> txtFiles = new ArrayList<>();
// 收集所有txt文件
Files.walkFileTree(Paths.get(WATCH_DIRECTORY), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toString().toLowerCase().endsWith(".txt")) {
txtFiles.add(file);
}
return FileVisitResult.CONTINUE;
}
});
// 按修改时间排序(从旧到新)
txtFiles.sort(Comparator.comparing(path -> {
try {
return Files.getLastModifiedTime(path).toMillis();
} catch (IOException e) {
return 0L;
}
}));
// 处理未处理过的文件
for (Path file : txtFiles) {
if (!processedFiles.contains(file)) {
processFile(file);
processedFiles.add(file);
}
}
} catch (IOException e) {
System.err.println("目录轮询错误: " + e.getMessage());
}
}
private static void processFile(Path file) {
try {
// 正确读取文件内容为字符串
String fileContent = new String(Files.readAllBytes(file)).trim();
if (fileContent.isEmpty()) {
System.out.println("文件内容为空,跳过: " + file.getFileName());
return;
}
// 发送UDP请求
sendUdpRequest(fileContent);
// 可选: 发送成功后移动或删除文件
Files.delete(file);
// 或移动到已处理目录
// Files.move(file, Paths.get("processed", file.getFileName()));
} catch (IOException e) {
System.err.println("处理文件错误 " + file.getFileName() + ": " + e.getMessage());
}
}
private static void sendUdpRequest(String hexString) {
hexString = hexString.replaceAll("\\s+", ""); // 移除所有空白字符
try (DatagramSocket socket = new DatagramSocket()) {
InetAddress serverAddress = InetAddress.getByName(SERVER_HOST);
byte[] data = hexStringToByteArray(hexString);
// 发送数据包
DatagramPacket packet = new DatagramPacket(
data, data.length, serverAddress, SERVER_PORT);
socket.send(packet);
System.out.println("已发送UDP数据包到 " + SERVER_HOST + ":" + SERVER_PORT);
// 接收响应(可选)
byte[] buffer = new byte[1024];
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.setSoTimeout(1000); // 3秒超时
try {
socket.receive(response);
String responseStr = new String(
response.getData(), 0, response.getLength());
System.out.println("服务器响应: " + responseStr);
} catch (IOException e) {
System.out.println("未收到服务器响应(超时)");
}
} catch (IOException e) {
System.err.println("UDP通信错误: " + e.getMessage());
}
}
// 十六进制字符串转字节数组的方法
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
if (len % 2 != 0) {
throw new IllegalArgumentException("十六进制字符串长度必须为偶数");
}
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}

View File

@ -0,0 +1,859 @@
package com.sipai.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.data.DeviceData;
import com.sipai.entity.data.PipelineEquipment;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import com.sipai.entity.data.SensorData;
import com.sipai.entity.mqtt.MqttConfig;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointES;
import com.sipai.entity.scada.MPointHistory;
import com.sipai.service.data.PipelineEquipmentMpointService;
import com.sipai.service.data.PipelineEquipmentService;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.service.scada.MPointHistoryService;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.AlarmType;
import com.sipai.tools.CommString;
import com.sipai.tools.CommUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.redisson.api.RBatch;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* 南昌项目upd接收数据处理
* sj 2025-05-21
*/
@Component
public class UDPServer implements CommandLineRunner {
@Value("${udp.server.port}") //端口
private int port;
@Value("${udp.server.enabled:true}") // 默认值为true
private boolean enabled;
private static final int BUFFER_SIZE = 1024;
@Autowired
private PipelineEquipmentService pipelineEquipmentService;
@Autowired
private PipelineEquipmentMpointService pipelineEquipmentMpointService;
@Autowired
private MPointService mPointService;
@Autowired
private MPointHistoryService mPointHistoryService;
@Autowired
private MqttConfigService mqttConfigService;
//缓存点位
private static final Map<String, String> dataCache = new ConcurrentHashMap<>();
@Override
public void run(String... args) throws Exception {
if (!enabled) {
System.out.println("UDP服务未启用");
return;
}
try (DatagramSocket socket = new DatagramSocket(port)) {
System.out.println("UDP服务端启动监听端口: " + port);
byte[] buffer = new byte[BUFFER_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
socket.receive(packet);
// System.out.println(CommUtil.nowDate() + "======收到来自 " + packet.getAddress() + ":" + packet.getPort() + " 的数据");
// 发送应答
String response = "@222\r\n";
byte[] responseData = response.getBytes(StandardCharsets.UTF_8);
DatagramPacket responsePacket = new DatagramPacket(
responseData, responseData.length,
packet.getAddress(), packet.getPort());
socket.send(responsePacket);
// 解析数据包
byte[] receivedData = new byte[packet.getLength()];
System.arraycopy(packet.getData(), 0, receivedData, 0, packet.getLength());
// 打印原始字节数组(十六进制格式)
// System.out.println("原始数据包(十六进制): " + bytesToHex(receivedData));
DeviceData data = parseDeviceData(Unpooled.wrappedBuffer(receivedData));
if (data != null) {
String jsonData = CommUtil.toJson(data);
JSONObject jsonObject = JSON.parseObject(jsonData);
System.out.println("站号收到数据:" + jsonObject.get("stationId")+""+jsonObject.get("startTime"));
JSONArray jsonArray = JSONArray.parseArray(jsonObject.get("sensorDataList").toString());
if (jsonArray != null && !jsonArray.isEmpty()) {
processSensorData(jsonObject, jsonArray, bytesToHex(receivedData));
}
}
}
} catch (IOException e) {
Logger logger = LoggerFactory.getLogger(UDPServer.class);
logger.error("UDP服务端启动异常", e);
e.printStackTrace();
}
}
//每次收到的报文存到D盘下 - 用于调试
private void logs(String type, String bytes, String path) {
try {
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义文件名(保持原来的格式)
String fileName = DateTimeFormatter
.ofPattern("yyyyMMdd_HHmmss")
.format(now) + "_" + type + ".txt";
// 定义文件路径D:/data_logs/年-月-日/自定义路径/
String dateDir = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(now);
Path dirPath = Paths.get("D:/data_logs_new/" + dateDir + "/" + path + "/");
if (!Files.exists(dirPath)) {
Files.createDirectories(dirPath); // 如果目录不存在,则创建
}
Path filePath = dirPath.resolve(fileName); // 完整路径
Files.write(filePath, bytes.getBytes()); // 写入内容到文件
} catch (IOException e) {
e.printStackTrace();
}
}
//分发到各个业务处理
private void processSensorData(JSONObject jsonObject, JSONArray jsonArray, String bytes) {
String stationId = jsonObject.get("stationId").toString();
switch (stationId.charAt(1)) {
case '1'://井盖
logs(stationId, bytes, "jinggai");
processManholeCoverData(jsonObject, jsonArray);
break;
case '2'://流量计
logs(stationId, bytes, "liuliang");
processFlowMeterData(jsonObject, jsonArray);
break;
case '3'://液位计
logs(stationId, bytes, "yewei");
processLevelMeterData(jsonObject, jsonArray);
break;
case '4'://电导率
logs(stationId, bytes, "diandao");
processConductivityMeterData(jsonObject, jsonArray);
break;
case '5'://雨量计
logs(stationId, bytes, "yuliang");
processRainGaugeData(jsonObject, jsonArray);
break;
case '6'://内涝监测
logs(stationId, bytes, "neilao");
processWaterloggingMonitoringData(jsonObject, jsonArray);
break;
default:
System.out.println("未知设备类型");
}
}
// 井盖处理逻辑
private void processManholeCoverData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理井盖数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
double batteryVoltage = jsonObject.getDouble("batteryVoltage"); // 获取电池电压
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
//单独处理电压
String channelName = stationId + "_V1";
String mpcode = getMpcodeFromCacheOrDB(stationId, channelName, "V1");
if (!mpcode.equals("未配置")) {
//推送kafka
mPointService.sendKafka4UDP("",mpcode, batteryVoltage, startTimeStr, 0, 1);
//推送mqtt
JSONArray jsonArray_mqtt = new JSONArray();
JSONObject jsonObject_mqtt = new JSONObject();
jsonObject_mqtt.put("mpcode", mpcode);
jsonObject_mqtt.put("value", batteryVoltage);
jsonObject_mqtt.put("time", startTimeStr);
jsonArray_mqtt.add(jsonObject_mqtt);
mqttConfigService.doSendView(jsonArray_mqtt,CommString.Mqtt_Topic_DATA);
}
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理模拟量数据 (type=4)
// System.out.println("\n模拟量数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(1, "A1"); // 信号强度
analogMappings.put(2, "A2"); // 基站序号
analogMappings.put(3, "A3"); // 井盖角度
analogMappings.put(4, "A4"); // 电阻值1
analogMappings.put(5, "A5"); // 电阻值2
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
// 创建新的JSONArray来存储处理后的报警数据
JSONArray processedAlarmData = new JSONArray();
// 处理报警量数据 (type=5)
// System.out.println("\n报警量数据:");
for (Object obj : jsonArray) {
JSONObject sensorData = (JSONObject) obj;
if (sensorData.getIntValue("type") == 5) {
int qValue = sensorData.getIntValue("qValue");
// 提取各报警位状态(0/1)
int voltageAlarm = (qValue & 0x0001) != 0 ? 1 : 0; // Q10
int waterAlarm = (qValue & 0x0002) != 0 ? 1 : 0; // Q11
int coverAlarm = (qValue & 0x0004) != 0 ? 1 : 0; // Q12
// 为每个报警位创建单独的数据对象
JSONObject voltageAlarmData = new JSONObject();
voltageAlarmData.put("type", 5);
voltageAlarmData.put("channel", 0); // Q10对应channel 0
voltageAlarmData.put("qValues", Collections.nCopies(dataCount, voltageAlarm));
JSONObject waterAlarmData = new JSONObject();
waterAlarmData.put("type", 5);
waterAlarmData.put("channel", 1); // Q11对应channel 1
waterAlarmData.put("qValues", Collections.nCopies(dataCount, waterAlarm));
JSONObject coverAlarmData = new JSONObject();
coverAlarmData.put("type", 5);
coverAlarmData.put("channel", 2); // Q12对应channel 2
coverAlarmData.put("qValues", Collections.nCopies(dataCount, coverAlarm));
// 添加到处理后的报警数据数组
processedAlarmData.add(voltageAlarmData);
processedAlarmData.add(waterAlarmData);
processedAlarmData.add(coverAlarmData);
} else {
// 非报警数据直接保留
processedAlarmData.add(sensorData);
}
}
// 处理报警数据存储
Map<Integer, String> alarmMappings = new HashMap<>();
alarmMappings.put(0, "Q10"); // 电压报警
alarmMappings.put(1, "Q11"); // 水浸报警
alarmMappings.put(2, "Q12"); // 开盖报警
processSensorData(stationId, processedAlarmData, 5, alarmMappings, "qValues", timePoints);
}
// 流量计处理逻辑
private void processFlowMeterData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理流量计数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理脉冲量数据 (type=1)
// System.out.println("\n脉冲量数据:");
Map<Integer, String> pulseMappings = new HashMap<>();
pulseMappings.put(1, "P1");
pulseMappings.put(2, "P2");
pulseMappings.put(3, "P3");
processSensorData(stationId, jsonArray, 1, pulseMappings, "accumulatedFlows", timePoints);
// 处理模拟量数据 (type=4)
// System.out.println("\n模拟量数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(1, "A1");
analogMappings.put(2, "A2");
analogMappings.put(4, "A4");
analogMappings.put(7, "A7");
analogMappings.put(8, "A8");
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
}
// 液位计处理逻辑
private void processLevelMeterData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理液位计数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理模拟量数据 (type=4)
// System.out.println("\n液位计模拟量数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(1, "A1"); // 信号接收功率(dBm)
analogMappings.put(2, "A2"); // 信噪比
analogMappings.put(3, "A3"); // 小区ID
analogMappings.put(4, "A4"); // 倾斜角度(°)
analogMappings.put(5, "A5"); // 电池电压(V)
analogMappings.put(6, "A6"); // 投入式液位(m)
analogMappings.put(8, "A8"); // 雷达水位(m)
analogMappings.put(10, "A10"); // 综合液位(m)
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
}
// 电导率仪处理逻辑
private void processConductivityMeterData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理电导率仪数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
double batteryVoltage = jsonObject.getDouble("batteryVoltage");
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
//单独处理电压
String channelName = stationId + "_V";
String mpcode = getMpcodeFromCacheOrDB(stationId, channelName, "V");
if (!mpcode.equals("未配置")) {
mPointService.sendKafka4UDP("",mpcode, batteryVoltage, startTimeStr, 0, 1);
//推送mqtt
JSONArray jsonArray_mqtt = new JSONArray();
JSONObject jsonObject_mqtt = new JSONObject();
jsonObject_mqtt.put("mpcode", mpcode);
jsonObject_mqtt.put("value", batteryVoltage);
jsonObject_mqtt.put("time", startTimeStr);
jsonArray_mqtt.add(jsonObject_mqtt);
mqttConfigService.doSendView(jsonArray_mqtt,CommString.Mqtt_Topic_DATA);
}
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理模拟量数据 (type=4)
// System.out.println("\n电导率仪数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(7, "A7"); // 电导率值
analogMappings.put(8, "A8"); // 温度值
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
}
// 雨量计处理逻辑
private void processRainGaugeData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理雨量计数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理模拟量数据 (type=4)
// System.out.println("\n雨量计数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(1, "A1"); // 雨量值
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
}
// 内涝监测处理逻辑
private void processWaterloggingMonitoringData(JSONObject jsonObject, JSONArray jsonArray) {
// System.out.println("开始处理内涝监测数据==============================================");
int dataCount = jsonObject.getIntValue("dataCount");
String startTimeStr = jsonObject.getString("startTime");
int intervalMinutes = jsonObject.getIntValue("intervalMinutes");
String stationId = jsonObject.getString("stationId");
// System.out.println("数据个数:" + dataCount);
// System.out.println("开始时间:" + startTimeStr);
// System.out.println("间隔分钟:" + intervalMinutes);
// 生成时间点序列
List<String> timePoints = generateTimePoints(startTimeStr, dataCount, intervalMinutes);
// 处理模拟量数据 (type=4)
// System.out.println("\n水位数据:");
Map<Integer, String> analogMappings = new HashMap<>();
analogMappings.put(13, "A13"); // 水位值(0x0D)
// analogMappings.put(14, "A14"); // 状态值(0x0D)
processSensorData(stationId, jsonArray, 4, analogMappings, "analogValues", timePoints);
// 处理脉冲量数据 (type=1)
// System.out.println("\n状态数据:");
Map<Integer, String> pulseMappings = new HashMap<>();
pulseMappings.put(14, "P14"); // 状态值(0x0E)
processSensorData(stationId, jsonArray, 1, pulseMappings, "accumulatedFlows", timePoints);
}
private DeviceData parseDeviceData(ByteBuf buf) {
// 查找起始符位置
int startIndex = -1;
for (int i = 0; i < buf.readableBytes() - 1; i++) {
if (buf.getByte(i) == (byte) 0xAB && buf.getByte(i + 1) == (byte) 0xCD) {
startIndex = i;
break;
}
}
if (startIndex == -1) {
// 没找到起始符,丢弃所有数据
buf.skipBytes(buf.readableBytes());
return null;
}
// 跳过起始符前的所有字节
buf.skipBytes(startIndex);
// 标记当前位置
buf.markReaderIndex();
// 验证起始符
byte b1 = buf.readByte();
byte b2 = buf.readByte();
if (b1 != (byte) 0xAB || b2 != (byte) 0xCD) {
buf.resetReaderIndex();
buf.skipBytes(1);
return null;
}
// 确保有足够数据读取长度
if (buf.readableBytes() < 2) {
buf.resetReaderIndex();
return null;
}
// 读取长度
int dataLength = buf.readUnsignedShort();
// 计算完整包长度
int totalLength = 2 + 2 + dataLength + 2; // AB CD + len + data + 结束符
// 确保有完整数据包
if (buf.readableBytes() < dataLength + 2) {
buf.resetReaderIndex();
return null;
}
// 读取完整数据包
ByteBuf frame = buf.readRetainedSlice(dataLength + 2);
DeviceData data = new DeviceData();
// 1. 基础信息解析
data.setStationId(frame.readUnsignedShort());
byte[] timeBytes = new byte[5];
frame.readBytes(timeBytes);
data.setStartTime(parseBcdTime(timeBytes));
data.setDataCount(frame.readUnsignedByte());
data.setIntervalMinutes(frame.readUnsignedByte());
data.setBatteryVoltage(frame.readUnsignedShort() / 100.0f);
data.setUploadCount(frame.readUnsignedShort());
//设备信息处理
int infoLength = frame.readUnsignedByte();
// 读取实际设备信息固定20字节
byte[] deviceInfo = new byte[20];
frame.readBytes(deviceInfo);
data.setDeviceInfo(new String(deviceInfo, StandardCharsets.US_ASCII).trim());
int bytesToSkip = 8; // 跳过预留的8字节
frame.skipBytes(bytesToSkip);
//解析传感器数据
List<SensorData> sensorDataList = new ArrayList<>();
while (frame.readableBytes() >= 2) {
int type = frame.readUnsignedByte();
int channel = frame.readUnsignedByte();
// System.out.printf("Parsing sensor: type=%02X, channel=%02X at pos=%d%n", type, channel, frame.readerIndex() - 2);
SensorData sensor = new SensorData();
sensor.setType(type);
sensor.setChannel(channel);
try {
switch (type) {
case 0x01: // 脉冲量
long yesterdayFlow = frame.readUnsignedIntLE();
sensor.setYesterdayFlow(yesterdayFlow);
List<Long> flows = new ArrayList<>();
for (int j = 0; j < data.getDataCount(); j++) {
if (frame.readableBytes() < 4) {
break;
}
flows.add(frame.readUnsignedIntLE());
}
sensor.setAccumulatedFlows(flows);
break;
case 0x02: // 开关量/报警量
// 每个通道只读取1字节状态值
if (frame.readableBytes() >= 1) {
int status = frame.readUnsignedByte();
List<Integer> statusList = new ArrayList<>();
statusList.add(status);
sensor.setDescription("开关量状态");
}
break;
case 0x41: // 不知道啥类型
// 不知道啥类型
if (frame.readableBytes() >= 1) {
}
break;
case 0x42: // 不知道啥类型
// 不知道啥类型
if (frame.readableBytes() >= 1) {
}
break;
case 0x43: // 不知道啥类型
// 不知道啥类型
if (frame.readableBytes() >= 1) {
}
break;
case 0x04: // 模拟量
List<Float> analogs = new ArrayList<>();
for (int j = 0; j < data.getDataCount(); j++) {
if (frame.readableBytes() < 4) {
break;
}
float value = 0.0f;
try {
// 智能井盖
if (String.valueOf(data.getStationId()).charAt(1) == '1') {
// 尝试不同的解析方式,根据通道类型选择合适的解析方法
switch (channel) {
case 1: // A1 信号强度 (dBm)
byte signalByte = frame.readByte();
frame.skipBytes(3); // 跳过剩余3字节
value = (float) signalByte;
break;
case 2: // A2 基站序号
value = (float) frame.readUnsignedIntLE();
break;
case 3: // A3 井盖角度
int angleInt = frame.readInt(); // 使用readInt()读取大端序
value = Float.intBitsToFloat(angleInt);
// 验证是否为合理的角度值
if (value < 0 || value > 360) {
frame.resetReaderIndex();
frame.skipBytes(j * 4);
int angleFixed = frame.readUnsignedShort();
frame.skipBytes(2);
value = (float) angleFixed / 100.0f;
}
break;
case 4: // A4 电阻值1
case 5: // A5 电阻值2
case 7: //
case 8: //
int resistanceInt1 = frame.readInt(); // 使用readInt()读取大端序
value = Float.intBitsToFloat(resistanceInt1);
break;
default: // 其他模拟量,默认使用浮点数解析
int intValue = frame.readIntLE();
value = Float.intBitsToFloat(intValue);
break;
}
}
// 流量计
if (String.valueOf(data.getStationId()).charAt(1) == '2') {
// 统一使用大端序读取IEEE754浮点数
int intValue = frame.readInt(); // 改为readInt()而不是readIntLE()
value = Float.intBitsToFloat(intValue);
// 保留3位小数
value = (float) (Math.round(value * 1000) / 1000.0);
// 格式化为3位小数不足补零
String formattedValue = String.format("%.3f", value); // 例如 7.4 → "7.400"
value = Float.parseFloat(formattedValue); // 转回float可选
}
// 液位计
if (String.valueOf(data.getStationId()).charAt(1) == '3') {
// 统一使用大端序读取IEEE754浮点数
int intValue = frame.readInt(); // 改为readInt()而不是readIntLE()
value = Float.intBitsToFloat(intValue);
// 保留3位小数
value = (float) (Math.round(value * 1000) / 1000.0);
// 格式化为3位小数不足补零
String formattedValue = String.format("%.3f", value); // 例如 7.4 → "7.400"
value = Float.parseFloat(formattedValue); // 转回float可选
}
// 电导率
/*if (String.valueOf(data.getStationId()).charAt(1) == '4') {
int intValue = frame.readIntLE();
value = Float.intBitsToFloat(intValue);
// 保留2位小数
value = (float) (Math.round(value * 100) / 100.0);
}*/
// 电导率
if (String.valueOf(data.getStationId()).charAt(1) == '4') {
// 改为使用大端序读取
int intValue = frame.readInt(); // 改为readInt()而不是readIntLE()
value = Float.intBitsToFloat(intValue);
// 保留2位小数
value = (float) (Math.round(value * 100) / 100.0);
}
// 雨量计
if (String.valueOf(data.getStationId()).charAt(1) == '5') {
// 改为使用大端序读取
int intValue = frame.readInt(); // 改为readInt()而不是readIntLE()
value = Float.intBitsToFloat(intValue);
// 保留2位小数
value = (float) (Math.round(value * 100) / 100.0);
}
// 内涝监测设备
if (String.valueOf(data.getStationId()).charAt(1) == '6') {
// 改为使用大端序读取
int intValue = frame.readInt(); // 改为readInt()而不是readIntLE()
value = Float.intBitsToFloat(intValue);
// 保留2位小数
value = (float) (Math.round(value * 100) / 100.0);
}
// 过滤异常值
if (Float.isNaN(value) || Float.isInfinite(value) || value < -1000000.0f || value > 1000000.0f) {
value = 0.0f;
}
} catch (Exception e) {
frame.skipBytes(4);
value = 0.0f;
}
analogs.add(value);
}
sensor.setAnalogValues(analogs);
// 智能井盖特定通道处理
if (String.valueOf(data.getStationId()).charAt(1) == '1') {
switch (channel) {
case 1: // A1信号强度
sensor.setDescription("A1信号强度");
break;
case 2: // A2基站序号
sensor.setDescription("A2基站序号");
break;
case 3: // A3井盖角度
sensor.setDescription("A3井盖角度");
break;
case 4: // A4电阻值1
sensor.setDescription("A4电阻值1");
break;
case 5: // A5电阻值2
sensor.setDescription("A5电阻值2");
break;
}
}
break;
case 0x05: // Q通道数据数字量输出
int qValue = frame.readUnsignedShort();
// 校验 qValue 范围0x0000 ~ 0xFFFF
if (qValue < 0 || qValue > 0xFFFF) {
throw new IllegalArgumentException("Invalid Q channel value: " + qValue);
}
// 解析各报警位状态
Map<AlarmType, Boolean> alarmStatus = new EnumMap<>(AlarmType.class);
for (AlarmType alarm : AlarmType.values()) {
alarmStatus.put(alarm, alarm.isTriggered(qValue));
}
// 构建报警描述
StringBuilder alarmDesc = new StringBuilder("Q通道状态: ");
for (AlarmType alarm : AlarmType.values()) {
alarmDesc.append(alarm.getDescription())
.append(alarmStatus.get(alarm) ? "触发" : "正常")
.append(", ");
}
sensor.setDescription(alarmDesc.toString().replaceAll(", $", ""));
// 存储原始报警值(可选)
sensor.setqValue(qValue);
sensor.setAlarmStatus(alarmStatus);
// 记录报警日志
if (alarmStatus.get(AlarmType.COVER_ALARM)) {
LoggerFactory.getLogger(UDPServer.class)
.warn("井盖开盖报警触发!站号: {}, Q值: {}", data.getStationId(), qValue);
}
break;
default:
int bytesToSkip2 = data.getDataCount() * 4;
if (frame.readableBytes() >= bytesToSkip2) {
frame.skipBytes(bytesToSkip2);
} else {
// System.err.printf("Not enough readable bytes to skip %d bytes. Current readable bytes: %d%n",
// bytesToSkip2, frame.readableBytes());
// 可选择抛出异常、记录日志或者做其他处理
}
continue;
}
sensorDataList.add(sensor);
} catch (Exception e) {
System.err.println("Error parsing sensor");
e.printStackTrace();
break;
}
// 检查是否到达结束符
if (frame.readableBytes() >= 2 && frame.getByte(frame.readerIndex()) == 0x0D && frame.getByte(frame.readerIndex() + 1) == 0x0A) {
// 跳过结束符
frame.skipBytes(2);
break;
}
}
data.setSensorDataList(sensorDataList);
return data;
}
private String parseBcdTime(byte[] bytes) {
// bytes: 19 05 29 10 47
int year = 2000 + ((bytes[0] >> 4) & 0xF) * 10 + (bytes[0] & 0xF);
int month = ((bytes[1] >> 4) & 0xF) * 10 + (bytes[1] & 0xF);
int day = ((bytes[2] >> 4) & 0xF) * 10 + (bytes[2] & 0xF);
int hour = ((bytes[3] >> 4) & 0xF) * 10 + (bytes[3] & 0xF);
int minute = ((bytes[4] >> 4) & 0xF) * 10 + (bytes[4] & 0xF);
return String.format("%04d-%02d-%02d %02d:%02d", year, month, day, hour, minute);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
/**
* 通用传感器数据处理方法
*
* @param stationId 站点id 用于redis组合key
* @param jsonArray 传感器数据数组
* @param type 要处理的数据类型
* @param channelMappings 通道映射
* @param valueFieldName 值字段名
* @param timePoints 时间点列表
*/
private void processSensorData(String stationId, JSONArray jsonArray, int type,
Map<Integer, String> channelMappings,
String valueFieldName,
List<String> timePoints) {
try {
for (Object obj : jsonArray) {
JSONObject sensorData = (JSONObject) obj;
if (sensorData.getIntValue("type") == type) {
int channel = sensorData.getIntValue("channel");
if (channelMappings.containsKey(channel)) {
String channelName = stationId + "_" + channelMappings.get(channel);
JSONArray values = sensorData.getJSONArray(valueFieldName);
if (values != null && !values.isEmpty()) {
//获取mpcode (优先从缓存拿)
String mpcode = getMpcodeFromCacheOrDB(stationId, channelName, channelMappings.get(channel));
if (!mpcode.equals("未配置")) {
JSONObject dataCache = new JSONObject();
JSONArray jsonArray_mqtt = new JSONArray();
for (int i = 0; i < values.size(); i++) {
String timePoint = timePoints.get(i);
timePoint = timePoint.length() == 16 ? timePoint + ":00" : timePoint;
Object value = values.get(i);
dataCache.put(timePoint, value);
//推送至kafka
mPointService.sendKafka4UDP("",mpcode, value, timePoint, i, values.size());
//添加到mqtt数组
JSONObject jsonObject_mqtt = new JSONObject();
jsonObject_mqtt.put("mpcode", mpcode);
jsonObject_mqtt.put("value", value);
jsonObject_mqtt.put("time", timePoint);
jsonArray_mqtt.add(jsonObject_mqtt);
}
//批量推送mqtt
mqttConfigService.doSendView(jsonArray_mqtt, CommString.Mqtt_Topic_DATA);
} else {
System.out.println("站点:" + stationId + " 标识:" + channelMappings.get(channel) + " 未配置");
}
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// 从缓存或数据库获取mpcode
private String getMpcodeFromCacheOrDB(String stationId, String channelName, String tag) {
// 先查缓存
String mpcode = dataCache.get(channelName);
if (mpcode != null) {
return mpcode;
}
// 缓存没有则查询数据库
List<PipelineEquipment> equipmentList = pipelineEquipmentService.selectListByWhere(
"where station_code = '" + stationId + "'");
if (equipmentList != null && !equipmentList.isEmpty()) {
List<PipelineEquipmentMpoint> mpointList = pipelineEquipmentMpointService.selectListByWhere(
"where pid = '" + equipmentList.get(0).getId() + "' and tag = '" + tag + "'");
if (mpointList != null && !mpointList.isEmpty()) {
mpcode = mpointList.get(0).getMpcode();
// 存入缓存
dataCache.put(channelName, mpcode);
return mpcode;
}
}
return "未配置"; // 或根据业务需求返回默认值
}
//时间生成方法
private List<String> generateTimePoints(String startTimeStr, int count, int intervalMinutes) {
List<String> timePoints = new ArrayList<>();
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date date = sdf.parse(startTimeStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
for (int i = 0; i < count; i++) {
timePoints.add(sdf.format(calendar.getTime()));
calendar.add(Calendar.MINUTE, intervalMinutes);
}
} catch (ParseException e) {
e.printStackTrace();
// 如果解析失败,使用简单的时间格式
for (int i = 0; i < count; i++) {
timePoints.add(startTimeStr + " +" + (i * intervalMinutes) + "分钟");
}
}
return timePoints;
}
}

View File

@ -0,0 +1,75 @@
package com.sipai.controller.check;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 普罗米修斯 监听接口
*/
@RestController
@RequestMapping("/check")
public class CheckServerController {
@RequestMapping("/server.do")
public String server() {
return "suc";
}
@RequestMapping("/testSendUdp.do")
public String testSendUdp() {
//修改成服务端的IP
// String serverHost = "132.120.132.77";
// String serverHost = "116.236.176.248";
String serverHost = "192.168.10.18";
int serverPort = 5006;
//智能井盖
// String hexString = "ABCD004D00002505121109013C016800001F484B33352D49493B56312E313B56312E302E303600000000000000000401C25000000402000000000403429E293C040447C35000040547C3500005010004A70D0A";
//流量仪
String hexString = "AB CD 01 C7 00 7B 25 05 19 16 18 0A 01 02 E2 00 00 00 48 38 36 45 3B 31 2E 33 3B 31 2E 30 2E 33 35 20 20 20 20 20 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 05 00 00 00 07 00 00 00 09 00 00 00 0B 00 00 00 0D 00 00 00 0E 00 00 00 10 00 00 00 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 03 00 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 05 00 00 00 07 00 00 00 09 00 00 00 0B 00 00 00 0D 00 00 00 0E 00 00 00 10 00 00 00 04 01 40 EC 62 C6 40 EC 62 C6 40 EC 62 C6 40 EC 62 C6 40 EC 62 C6 40 EC D0 CD 40 48 F5 C3 40 48 F5 C3 40 48 F5 C3 40 48 F5 C3 04 02 40 EB 86 B8 40 EB 86 B8 40 EB 86 B8 40 EB 86 B8 40 EB 86 B8 40 EB F4 BF 3D FB E7 6D 3D FB E7 6D 3D FB E7 6D 3D FB E7 6D 04 03 41 F0 00 00 41 B0 00 00 41 F8 00 00 41 B8 00 00 41 B8 00 00 41 F8 00 00 41 F8 00 00 41 F8 00 00 41 F8 00 00 41 F8 00 00 04 04 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 41 BB 99 9A 04 07 42 ED 99 9A 42 ED 99 9A 42 ED 99 9A 42 ED 99 9A 42 ED 99 9A 42 ED 99 9A 42 B4 00 00 42 B4 00 00 42 B4 00 00 42 B4 00 00 04 08 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 3E 40 83 12 05 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6B 0D 0A";
//厂家传的异常数据
// String hexString = "AA AA B7 56 0E 25 06 03 10 15 08 31 02 E1 30 11 00 00 0B 47 00 00 0F 50 00 03 00 03 00 04 00 04 00 03 00 04 00 03 12 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 00 0B 47 00 00 0F 4C 00 03 00 03 00 04 00 04 00 03 00 04 00 03 31 00 02 00 02 00 02 00 02 00 02 00 02 00 02 00 02 32 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 33 04 B0 04 B0 04 B0 04 B0 04 B0 04 B0 04 B0 04 B0 34 07 9E 07 9E 07 9C 07 9D 07 99 07 99 07 9A 07 98 37 00 12 00 0A 00 0E 00 0E 00 0E 00 0E 00 0E 00 0E 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 0A";
hexString = hexString.replaceAll("\\s+", ""); // Remove all whitespace
byte[] data = hexStringToByteArray(hexString);
try (DatagramSocket socket = new DatagramSocket()) {
InetAddress serverAddress = InetAddress.getByName(serverHost);
// 发送数据包
DatagramPacket packet = new DatagramPacket(
data, data.length, serverAddress, serverPort);
socket.send(packet);
System.out.println("已发送数据包到服务器");
// 接收响应
byte[] buffer = new byte[1024];
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
String responseStr = new String(
response.getData(), 0, response.getLength());
System.out.println("服务器响应: " + responseStr);
} catch (IOException e) {
e.printStackTrace();
}
return "suc";
}
// 十六进制字符串转字节数组的方法
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}

View File

@ -0,0 +1,170 @@
package com.sipai.controller.data;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sipai.entity.base.Result;
import com.sipai.entity.common.PageData;
import com.sipai.entity.data.PipeTopicMpoint;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import com.sipai.entity.scada.MPoint;
import com.sipai.service.data.PipeTopicMpointService;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.CommUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 管网专题页点位控制器
*/
@RestController
@RequestMapping("/pipeTopicMPoint")
public class PipeTopicMPointController {
@Autowired
private PipeTopicMpointService pipeTopicMpointService;
@Autowired
private MPointService mPointService;
/**
* 根据主键查询点位信息
*/
@GetMapping("/selectById.do")
public Result selectByPrimaryKey(@RequestParam Integer id) {
PipeTopicMpoint mpoint = pipeTopicMpointService.selectByPrimaryKey(id);
if (mpoint != null) {
return Result.success(mpoint);
} else {
return Result.failed("点位不存在");
}
}
/**
* 新增点位信息
*/
@PostMapping("/save.do")
public String save(@ModelAttribute PipeTopicMpoint mpoint) {
int res = pipeTopicMpointService.insert(mpoint);
if (res > 0) {
return CommUtil.toJson(Result.success(mpoint.getId()));
} else {
return CommUtil.toJson(Result.failed("新增失败"));
}
}
/**
* 更新点位信息
*/
@PostMapping("/update.do")
public String update(@ModelAttribute PipeTopicMpoint mpoint) {
boolean res = pipeTopicMpointService.update(mpoint);
return CommUtil.toJson(res ? Result.success(1) : Result.failed("更新失败"));
}
/**
* 根据主键删除点位
*/
@PostMapping("/deleteById.do")
public String deleteById(@RequestParam Integer id) {
boolean res = pipeTopicMpointService.delete(id);
return CommUtil.toJson(res ? Result.success(1) : Result.failed("删除失败"));
}
/**
* 批量删除点位
*/
@PostMapping("/deleteBatch.do")
public String deleteBatch(@RequestBody List<Integer> idList) {
boolean res = pipeTopicMpointService.deleteBatch(idList);
return CommUtil.toJson(res ? Result.success(1) : Result.failed("批量删除失败"));
}
/**
* 分页查询点位列表
*/
@GetMapping("/list.do")
public PageData<PipeTopicMpoint> selectList(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String type) {
PageHelper.startPage(pageNum, pageSize);
String where = "where 1=1";
if (type != null && !type.isEmpty()) {
where += " AND type = '" + type + "'";
}
List<PipeTopicMpoint> list = pipeTopicMpointService.selectListByWhere(where);
PageInfo<PipeTopicMpoint> pageInfo = new PageInfo<>(list);
return new PageData<>(pageInfo);
}
/**
* 获取 “管网专题页” 数据
*
* @param type
* @return
*/
@GetMapping("/getData.do")
public Result getData(@RequestParam(required = false) String type) {
String where = "where 1=1";
if (type != null && !type.isEmpty()) {
where += " AND type = '" + type + "'";
}
// 定义 type 含义的映射关系
Map<String, String> typeMap = new HashMap<>();
typeMap.put("0", "污水厂");
typeMap.put("1", "新城南大道污水泵站");
typeMap.put("2", "神农西大道雨水泵站");
typeMap.put("3", "新祺周大道雨水泵站");
JSONArray jsonArray = new JSONArray();
try {
List<PipeTopicMpoint> list = pipeTopicMpointService.selectListByWhere(where);
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
PipeTopicMpoint item = list.get(i);
JSONObject jsonObject = new JSONObject();
// 添加 type 信息(如果 type 存在)
if (type != null && !type.isEmpty()) {
jsonObject.put("type", type);
jsonObject.put("typeName", typeMap.getOrDefault(type, "未知类型"));
}
if (item.getIsConstant() == 1) { // 常量
if (item.getPointName().equals("调度模式")) {
jsonObject.put("parmvalue", "输送模式-常规输送");
} else {
jsonObject.put("parmvalue", item.getConstantValue());
}
jsonObject.put("mpcode", item.getPointCode());
jsonObject.put("mpname", item.getPointName());
jsonObject.put("measuredt", CommUtil.nowDate());
jsonObject.put("unit", "");
} else { // 读点位
MPoint mPoint = mPointService.selectById("",item.getPointCode());
if (mPoint != null) {
jsonObject.put("mpcode", mPoint.getMpointcode());
jsonObject.put("mpname", mPoint.getParmname());
jsonObject.put("parmvalue", mPoint.getParmvalue() != null ? mPoint.getParmvalue() : 0);
jsonObject.put("measuredt", mPoint.getMeasuredt());
jsonObject.put("unit", mPoint.getUnit() != null ? mPoint.getUnit() : "");
}
}
jsonArray.add(jsonObject);
}
}
return Result.success(jsonArray);
} catch (Exception e) {
return Result.failed("无数据");
}
}
}

View File

@ -0,0 +1,271 @@
package com.sipai.controller.data;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sipai.entity.base.Result;
import com.sipai.entity.common.PageData;
import com.sipai.entity.data.PipelineEquipment;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import com.sipai.entity.enums.DeviceTypeEnum;
import com.sipai.service.data.PipelineEquipmentMpointService;
import com.sipai.service.data.PipelineEquipmentService;
import com.sipai.tools.CommUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 管网设备列表
*/
@RestController
@RequestMapping("/pipeline-equipment")
public class PipelineEquipmentController {
@Autowired
private PipelineEquipmentService pipelineEquipmentService;
@Autowired
private PipelineEquipmentMpointService pipelineEquipmentMpointService;
// 根据主键查询管道设备信息
@GetMapping("/selectById.do")
public Result selectByPrimaryKey(@RequestParam(value = "id") Integer id) {
PipelineEquipment pipelineEquipment = pipelineEquipmentService.selectByPrimaryKey(id);
if(pipelineEquipment!=null){
return Result.success(pipelineEquipment);
}else{
return Result.failed("设备不存在");
}
}
// 删除指定主键的管道设备信息
@PostMapping("/deleteById.do")
public String deleteByPrimaryKey(@RequestParam(value = "id") Integer id) {
boolean res = pipelineEquipmentService.delete(id);
if(res){
Result result = Result.success(1);
return CommUtil.toJson(result);
}else{
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 删除指定主键的管道设备信息
@PostMapping("/deleteByIds.do")
public String deleteByIds(@RequestParam(value = "id") Integer id) {
boolean res = pipelineEquipmentService.delete(id);
if(res){
Result result = Result.success(1);
return CommUtil.toJson(result);
}else{
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
//新增
@PostMapping("/save.do")
public String save(@ModelAttribute PipelineEquipment pipelineEquipment) {
int res = pipelineEquipmentService.insert(pipelineEquipment);
if (res > 0) {
int generatedId = pipelineEquipment.getId();
Result result = Result.success(generatedId);
return CommUtil.toJson(result);
}else{
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
//修改
@PostMapping("/update.do")
public String update(@ModelAttribute PipelineEquipment pipelineEquipment) {
boolean res = pipelineEquipmentService.update(pipelineEquipment);
if(res){
Result result = Result.success(1);
return CommUtil.toJson(result);
}else{
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
/**
* 分页查询管道设备列表
* @param pageNum
* @param pageSize
* @param equipmentTypeId 类型id
* @param stationCode 站号
* @param status 1在线 0离线 null为未检测
* @return
*/
@GetMapping("/list.do")
public PageData<PipelineEquipment> selectListByWhere(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String equipmentTypeId,
@RequestParam(required = false) String stationCode,
@RequestParam(required = false) String status) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 构建查询条件
String where = "where 1=1";
//类型筛选
if (equipmentTypeId != null && !equipmentTypeId.isEmpty()) {
where += " AND equipment_type = '" + equipmentTypeId + "'";
}
//站号筛选
if (stationCode != null && !stationCode.isEmpty()) {
where += " AND station_code = '" + stationCode + "'";
}
//状态筛选
if (status != null && !status.isEmpty()) {
where += " AND status = '" + status + "'";
}
// 执行查询
List<PipelineEquipment> list = pipelineEquipmentService.selectListByWhere(where);
// 封装分页信息
PageInfo<PipelineEquipment> pageInfo = new PageInfo<>(list);
// 返回分页数据
return new PageData<>(pageInfo);
}
/**
* 获取管网设备类型
* @return
*/
@GetMapping("/device-types")
public List<Map<String, String>> getDeviceTypes() {
List<Map<String, String>> deviceTypes = new ArrayList<>();
for (DeviceTypeEnum deviceType : DeviceTypeEnum.values()) {
Map<String, String> deviceTypeMap = new HashMap<>();
deviceTypeMap.put("typeName", deviceType.getTypeName());
deviceTypeMap.put("typeCode", deviceType.getTypeCode());
deviceTypes.add(deviceTypeMap);
}
return deviceTypes;
}
/**
* 手动初始化关联 设备-点位 关系
*
* @return
*/
@GetMapping("/hand-save.do")
public String handSave() {
//井盖
List<PipelineEquipment> list = pipelineEquipmentService.selectListByWhere("where equipment_type = '1'");
for (int i = 0; i < list.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A1", "A2", "A3", "A4", "A5", "Q10", "Q11", "Q12", "V1"};
String[] names = new String[]{"信号强度", "基站序号", "井盖角度", "电阻值1", "电阻值2", "电压报警", "水浸报警", "开盖报警", "电池电压"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
//流量计
List<PipelineEquipment> list2 = pipelineEquipmentService.selectListByWhere("where equipment_type = '2'");
for (int i = 0; i < list2.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A1", "A2", "A4", "A7", "A8", "P1", "P2", "P3"};
String[] names = new String[]{"过水面积","液位","温度","瞬时流量","流速","正向累计","反向累计","实际累计"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list2.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list2.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
//液位计
List<PipelineEquipment> list3 = pipelineEquipmentService.selectListByWhere("where equipment_type = '3'");
for (int i = 0; i < list3.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A1", "A2", "A3", "A4", "A5", "A6", "A8", "A10"};
String[] names = new String[]{"信号接收功率","信噪比","小区ID","倾斜角度","电池电压","投入式液位","雷达水位","综合液位"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list3.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list3.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
//电导率
List<PipelineEquipment> list4 = pipelineEquipmentService.selectListByWhere("where equipment_type = '4'");
for (int i = 0; i < list4.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A7", "A8", "V"};
String[] names = new String[]{"电导率","温度","电池电压"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list4.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list4.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
//雨量计
List<PipelineEquipment> list5 = pipelineEquipmentService.selectListByWhere("where equipment_type = '5'");
for (int i = 0; i < list5.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A1"};
String[] names = new String[]{"雨量值"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list5.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list5.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
//内涝监测
List<PipelineEquipment> list6 = pipelineEquipmentService.selectListByWhere("where equipment_type = '6'");
for (int i = 0; i < list6.size(); i++) {
//格式KCGW_21001_A1
String[] codes = new String[]{"A13", "P14"};
String[] names = new String[]{"水位", "状态(有水/无水)"};
for (int j = 0; j < codes.length; j++) {
String mpcode = "KCGW_" + list6.get(i).getStationCode() + "_" + codes[j];
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(list6.get(i).getId());
pipelineEquipmentMpoint.setMpcode(mpcode);
pipelineEquipmentMpoint.setMpname(names[j]);
pipelineEquipmentMpoint.setTag(codes[j]);
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
return "suc";
}
}

View File

@ -0,0 +1,136 @@
package com.sipai.controller.data;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sipai.entity.base.Result;
import com.sipai.entity.common.PageData;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import com.sipai.entity.data.PipelineMpointLibrary;
import com.sipai.service.data.PipelineEquipmentMpointService;
import com.sipai.service.data.PipelineMpointLibraryService;
import com.sipai.tools.CommUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 管网设备附属点位列表
*/
@RestController
@RequestMapping("/pipeline-equipment-mpoint")
public class PipelineEquipmentMpointController {
@Autowired
private PipelineEquipmentMpointService pipelineEquipmentMpointService;
@Autowired
private PipelineMpointLibraryService pipelineMpointLibraryService;
// 根据主键查询管道设备与测点关联信息
@GetMapping("/selectById.do")
public Result selectByPrimaryKey(@RequestParam(value = "id") Integer id) {
PipelineEquipmentMpoint mpoint = pipelineEquipmentMpointService.selectByPrimaryKey(id);
if (mpoint != null) {
return Result.success(mpoint);
} else {
return Result.failed("关联信息不存在");
}
}
// 删除指定主键的管道设备与测点关联信息
@PostMapping("/deleteById.do")
public String deleteByPrimaryKey(@RequestParam(value = "id") Integer id) {
boolean res = pipelineEquipmentMpointService.delete(id);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 新增管道设备与测点关联信息
@PostMapping("/save.do")
public String save(@ModelAttribute PipelineEquipmentMpoint mpoint) {
boolean res = pipelineEquipmentMpointService.insert(mpoint);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 修改管道设备与测点关联信息
@PostMapping("/update.do")
public String update(@ModelAttribute PipelineEquipmentMpoint mpoint) {
boolean res = pipelineEquipmentMpointService.update(mpoint);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 分页查询管道设备与测点关联信息列表
@GetMapping("/list.do")
public PageData<PipelineEquipmentMpoint> selectListByWhere(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String pid) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 构建查询条件
String where = "where 1=1";
if (pid != null && !pid.isEmpty()) {
where += " AND pid = '" + pid + "'";
}
// 执行查询
List<PipelineEquipmentMpoint> list = pipelineEquipmentMpointService.selectListByWhere(where);
// 封装分页信息
PageInfo<PipelineEquipmentMpoint> pageInfo = new PageInfo<>(list);
// 返回分页数据
return new PageData<>(pageInfo);
}
/**
* 根据类型一键导入
*
* @param equipmentTypeId
* @return
*/
@PostMapping("/import4Type.do")
public String import4Type(@RequestParam(required = true) Integer pid,
@RequestParam(required = true) String equipmentTypeId) {
try{
// 构建查询条件
String where = "where 1=1 AND equipment_type = '" + equipmentTypeId + "'";
// 执行查询
List<PipelineMpointLibrary> list = pipelineMpointLibraryService.selectListByWhere(where);
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
PipelineEquipmentMpoint pipelineEquipmentMpoint = new PipelineEquipmentMpoint();
pipelineEquipmentMpoint.setPid(pid);
pipelineEquipmentMpoint.setTag(list.get(i).getCode());
pipelineEquipmentMpoint.setMpname(list.get(i).getName());
pipelineEquipmentMpointService.insert(pipelineEquipmentMpoint);
}
}
Result result = Result.success(1);
return CommUtil.toJson(result);
}catch (Exception e){
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
}

View File

@ -0,0 +1,106 @@
package com.sipai.controller.data;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sipai.entity.base.Result;
import com.sipai.entity.common.PageData;
import com.sipai.entity.data.PipelineMpointLibrary;
import com.sipai.service.data.PipelineMpointLibraryService;
import com.sipai.tools.CommUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/pipeline-mpoint-library")
public class PipelineMpointLibraryController {
@Autowired
private PipelineMpointLibraryService pipelineMpointLibraryService;
// 根据主键查询记录
@GetMapping("/selectById.do")
public PipelineMpointLibrary selectByPrimaryKey(@RequestParam(value = "id") String id) {
return pipelineMpointLibraryService.selectByPrimaryKey(id);
}
// 删除指定主键的记录
@PostMapping("/deleteById.do")
public String deleteByPrimaryKey(@RequestParam(value = "id") String id) {
boolean res = pipelineMpointLibraryService.delete(id);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 多删指定主键的记录
@PostMapping("/deleteByIds.do")
public String deleteByIds(@RequestParam(value = "ids") List<String> idList) {
int count = pipelineMpointLibraryService.deleteBatch(idList);
if (count > 0) {
Result result = Result.success(count);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 插入记录
@PostMapping("/save.do")
public String save(@ModelAttribute PipelineMpointLibrary pipelineMpointLibrary) {
pipelineMpointLibrary.setId(CommUtil.getUUID());
boolean res = pipelineMpointLibraryService.insert(pipelineMpointLibrary);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 根据主键选择性更新记录
@PostMapping("/update.do")
public String update(@ModelAttribute PipelineMpointLibrary pipelineMpointLibrary) {
boolean res = pipelineMpointLibraryService.update(pipelineMpointLibrary);
if (res) {
Result result = Result.success(1);
return CommUtil.toJson(result);
} else {
Result result = Result.failed("0");
return CommUtil.toJson(result);
}
}
// 分页查询列表
@GetMapping("/list.do")
public PageData<PipelineMpointLibrary> selectListByWhere(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String equipmentTypeId) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 构建查询条件
String where = "where 1=1";
if (equipmentTypeId != null && !equipmentTypeId.isEmpty()) {
where += " AND equipment_type = '" + equipmentTypeId + "'";
}
// 执行查询
List<PipelineMpointLibrary> list = pipelineMpointLibraryService.selectListByWhere(where);
// 封装分页信息
PageInfo<PipelineMpointLibrary> pageInfo = new PageInfo<>(list);
// 返回分页数据
return new PageData<>(pageInfo);
}
}

View File

@ -0,0 +1,26 @@
package com.sipai.controller.kafka;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/kafka")
public class KafkaController {
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@GetMapping("/testSendMessage")
public String readValue() {
String topic = "my-topic"; // 替换为你的主题名
String message = "Hello, Kafka!";
// 发送消息
kafkaTemplate.send(topic, message);
System.out.println("消息已发送: " + message);
return "suc";
}
}

View File

@ -0,0 +1,145 @@
package com.sipai.controller.mqtt;
import com.sipai.entity.mqtt.MqttConfig;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.tools.Result;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/04/22/14:30
* @Description: mqtt配置主表
*/
@Controller
@RequestMapping("/mqttConfig")
public class MqttConfigController {
@Autowired
private MqttConfigService mqttConfigService;
@GetMapping("/getById")
public String getById() {
MqttConfig mqttConfig = mqttConfigService.selectByPrimaryKey("2");
if (mqttConfig != null) {
System.out.println(mqttConfig.getClientName());
} else {
System.out.println("无数据");
}
return "index";
}
//连接代理
@RequestMapping("/connectStart.do")
@ResponseBody
public Result connectStart(HttpServletRequest request, Model model) {
String id = request.getParameter("id");
mqttConfigService.connect(id);
Result res = Result.success(1);
return res;
}
/**
* 连接 mqtt
*
* @param request
* @param model
*/
/*@GetMapping("/connect.do")
public void connect(HttpServletRequest request, Model model) {
String ids = request.getParameter("ids");
if (ids != null && !ids.equals("")) {
String[] idstr = ids.split(",");
for (int i = 0; i < idstr.length; i++) {
MqttConfig mqttConfig = mqttConfigService.selectByPrimaryKey(idstr[i]);
if (mqttConfig != null) {
String str = "http://" + request.getServerName() + ":" + mqttConfig.getTomcatPort() + "/mqttConfig/connectStart.do?id=" + idstr[i];
this.doPost(str);
}
}
}
}*/
@GetMapping("/connect.do")
@ResponseBody
public Result connect(HttpServletRequest request, Model model) {
String ids = request.getParameter("ids");
if (ids != null && !ids.equals("")) {
String[] idstr = ids.split(",");
for (int i = 0; i < idstr.length; i++) {
MqttConfig mqttConfig = mqttConfigService.selectByPrimaryKey(idstr[i]);
if (mqttConfig != null) {
//String str = "http://" + request.getServerName() + ":" + mqttConfig.getTomcatPort() + "/mqttConfig/connectStart.do?id=" + idstr[i];
String str = "http://" + mqttConfig.getTomcatPort() + "/mqttConfig/connectStart.do?id=" + idstr[i];
this.doPost(str);
}
}
}
Result res = Result.success(1);
return res;
}
public String doPost(String URL) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
HttpURLConnection conn = null;
try {
java.net.URL url = new URL(URL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
//发送POST请求必须设置为true
conn.setDoOutput(true);
conn.setDoInput(true);
//设置连接超时时间和读取超时时间
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
//获取输出流
out = new OutputStreamWriter(conn.getOutputStream());
String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
out.write(jsonStr);
out.flush();
out.close();
//取得输入流并使用Reader读取
if (200 == conn.getResponseCode()) {
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
System.out.println(line);
}
} else {
System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return result.toString();
}
}

View File

@ -0,0 +1,41 @@
package com.sipai.controller.mqtt;
import com.sipai.entity.mqtt.MqttConfigTopic;
import com.sipai.service.mqtt.MqttConfigTopicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/04/22/14:42
* @Description: mqtt配置主表
*/
@Controller
@RequestMapping("/mqttConfigTopic")
public class MqttConfigTopicController {
@Autowired
private MqttConfigTopicService mqttConfigTopicService;
@RequestMapping("/save.do")
@ResponseBody
public Integer save(HttpServletRequest request, Model model,
@ModelAttribute("mqttConfigTopic") MqttConfigTopic mqttConfigTopic) {
return mqttConfigTopicService.insert(mqttConfigTopic);
}
@RequestMapping("/delete.do")
@ResponseBody
public int delete(HttpServletRequest request, Model model,
@ModelAttribute("id") String id) {
return mqttConfigTopicService.deleteByPrimaryKey(id);
}
}

View File

@ -0,0 +1,408 @@
package com.sipai.controller.mqtt;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.mqtt.MqttConfig;
import com.sipai.entity.mqtt.MqttConfigTopic;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointES;
import com.sipai.entity.user.Company;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.service.mqtt.MqttConfigTopicService;
import com.sipai.service.mqtt.MqttService;
import com.sipai.service.scada.MPointService;
import com.sipai.service.user.CompanyService;
import com.sipai.tools.CommUtil;
import com.sipai.tools.Result;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.spring.web.json.Json;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Controller
@RequestMapping("/mqtt")
public class MqttController {
@Autowired
private MqttService mqttService;
@Autowired
private CompanyService companyService;
@Autowired
private MPointService mPointService;
@Autowired
private MqttConfigService mqttConfigService;
@Autowired
private MqttConfigTopicService mqttConfigTopicService;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private RedissonClient redissonClient;
/**
* 用于提供云平台 查询指定网关是否在线 (单个网关)
* sj 2021-05-25
*/
@RequestMapping("/getClientStatus.do")
@ResponseBody
public String getClientStatus(HttpServletRequest request, Model model) {
String unitId = request.getParameter("unitId");//厂id
String line = null;
try {
URL url = new URL("http://172.16.242.16:28083/api/v4/clients/" + unitId + "_01");
Base64 b = new Base64();
String encoding = b.encodeAsString(new String("admin:public").getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = (InputStream) connection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(content));
while ((line = in.readLine()) != null) {
return line;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 用于提供云平台 返回所有在线的网关 (所有网关)
* sj 2021-05-25
*/
@RequestMapping("/getClientListStatus.do")
@ResponseBody
public String getClientListStatus() {
String line = null;
try {
URL url = new URL("http://172.16.242.16:28083/api/v4/clients/");
Base64 b = new Base64();
String encoding = b.encodeAsString(new String("admin:public").getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = (InputStream) connection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(content));
while ((line = in.readLine()) != null) {
return line;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(line);
return "";
}
/**
* 根据厂id返回该厂所有的网关在线状态 必须配置了_COM点
* sj 2021-08-12
*/
@RequestMapping("/getClientListStatus4UnitId.do")
@ResponseBody
public String getClientListStatus4UnitId(HttpServletRequest request, Model model,
@ModelAttribute("unitId") String unitId) {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
BoolQueryBuilder childBoolQueryBuilder = QueryBuilders.boolQuery();
childBoolQueryBuilder.must(QueryBuilders.matchQuery("bizid", unitId));
childBoolQueryBuilder.must(QueryBuilders.matchQuery("signaltag", "COMMU"));
boolQueryBuilder.should(childBoolQueryBuilder);
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 300));
//先根据es找到改厂所有的通讯点然后获取mpointId去网关中查询在线状态
List<MPoint> runMPoint = this.mPointService.selectListByWhere4Es(nativeSearchQueryBuilder);
String str = "";
String line = null;
JSONArray jsonArray = new JSONArray();
if (runMPoint.size() > 0) {
//循环所有网关
for (int i = 0; i < runMPoint.size(); i++) {
String mpointid = runMPoint.get(i).getMpointid();
String parmname = runMPoint.get(i).getParmname();
//网关id
mpointid = mpointid.replace("_COM", "");
try {
URL url = new URL("http://172.16.242.16:28083/api/v4/clients/" + mpointid);
Base64 b = new Base64();
String encoding = b.encodeAsString(new String("admin:public").getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = (InputStream) connection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(content));
JSONObject jsonObject = JSONObject.parseObject(in.readLine());
String data = jsonObject.get("data").toString();
JSONArray jsonArrayStr = JSONArray.parseArray(data);
if (jsonArrayStr.size() > 0) {
//获取第一个网关对象
JSONObject jsonObjectStr = (JSONObject) jsonArrayStr.get(0);
JSONObject jsonData = new JSONObject();
jsonData.put("clientid", jsonObjectStr.get("clientid"));
jsonData.put("parmname", parmname);
jsonData.put("connected", true);//在线
jsonArray.add(jsonData);
} else {
JSONObject jsonData = new JSONObject();
jsonData.put("clientid", mpointid);
jsonData.put("parmname", parmname);
jsonData.put("connected", false);//不在线
jsonArray.add(jsonData);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return jsonArray.toString();
}
/**
* 用于提供云平台 给plc发布指令接口
* sj 2021-05-25
*/
@RequestMapping("/doPublish4Vue.do")
@ResponseBody
public String doPublish4Vue(HttpServletRequest request, Model model) {
String mpid = request.getParameter("mpid");//测量点Id
String bizType = request.getParameter("bizType");//网关编号
String value = request.getParameter("value");//指令下发的值
String userId = request.getParameter("userId");//操作人员id
String rate = request.getParameter("rate");//倍率
String directtype = request.getParameter("directtype");//取反类型 1为取反 其余为正常
String topic = bizType + "_DOWN";
JSONObject jsonObject = new JSONObject();
String bizId = bizType.substring(0, 7);
Company company = companyService.selectByPrimaryKey(bizId);
if (company != null) {
bizId = company.getPid();
}
/*
取反操作
*/
if (directtype != null && directtype.equals("1")) {
//取反
if (value.equals("0")) {
value = "1";
} else if (value.equals("1")) {
value = "0";
} else {
//正常
}
} else {
//正常
}
BigDecimal val = null;
if (rate != null && !rate.equals("0")) {
BigDecimal num1 = new BigDecimal(value);
BigDecimal num2 = new BigDecimal(rate);
// MPoint mPoint = mPointService.selectById(bizId, mpid);
MPoint mPoint = mPointService.selectById(bizId,mpid);
//AO根据写入的小数位赋值
if (mPoint != null && mPoint.getSignaltype().equals("AO")) {
BigDecimal bd = new BigDecimal(String.valueOf(value));
// bd.scale() 为小数位
val = num1.divide(num2, bd.scale(), BigDecimal.ROUND_HALF_UP);
}
//DO截取0位
if (mPoint != null && mPoint.getSignaltype().equals("DO")) {
val = num1.divide(num2, 0, BigDecimal.ROUND_HALF_UP);
}
jsonObject.put("TagValue", val);
} else {
String str = String.valueOf(value);//浮点变量a转换为字符串str
int idx = str.lastIndexOf(".");//查找小数点的位置
if (idx == -1) {
jsonObject.put("TagValue", value);
} else {
String strNum = str.substring(0, idx);//截取从字符串开始到小数点位置的字符串,就是整数部分
int num = Integer.valueOf(strNum);//把整数部分通过Integer.valueof方法转换为数字
jsonObject.put("TagValue", num);
}
}
jsonObject.put("method", "setValue");
jsonObject.put("TagName", mpid);
int res = this.mqttService.doPublish(jsonObject, topic, userId, bizId);
String json = null;
if (res == 0) {
Result result = Result.success(res);
json = CommUtil.toJson(result);
} else {
Result result = Result.failed("指令下发失败");
json = CommUtil.toJson(result);
}
return json;
}
/**
* 网关数据全部召回(Recall) 传bizid召回该厂该网关的所有数据
* sj 2021-06-25
*
* @param request
* @param model
* @return
*/
@RequestMapping("/doRecall.do")
@ResponseBody
public String doRecall(HttpServletRequest request, Model model) {
String unitId = request.getParameter("unitId");//厂id
JSONObject jsonObject = new JSONObject();
jsonObject.put("command", "Upload immediately");
mqttService.doRecall(unitId, jsonObject);
Result result = Result.success("");
String json = null;
json = CommUtil.toJson(result);
return json;
}
/**
* 前端传主题,根据配置,查询属于哪个代理
* sj 2021-09-15
*
* @param request
* @param model
* @return
*/
@RequestMapping("/getEmqx4Topic.do")
@ResponseBody
public String getEmqx4Topic(HttpServletRequest request, Model model) {
String topic = request.getParameter("topic");//厂id
if (topic != null && topic.contains("_VUE")) {
topic = topic.replace("_VUE", "");
}
JSONObject jsonObject = mqttConfigService.getEmqxHost4WS(topic);
Result result = null;
if (jsonObject != null && jsonObject.size() > 0) {
result = Result.success(jsonObject);
} else {
result = Result.failed("无法查询该代理地址");
}
String json = null;
json = CommUtil.toJson(result);
return json;
}
/**
* 演示推送开始
*
* @param request
* @param model
* @return
*/
@RequestMapping("/startSend.do")
@ResponseBody
public String startSend(HttpServletRequest request, Model model) {
String mp1 = "SPF_XFJZ1_FV2"; //15-50 1秒加1
String mp2 = "SPF_XFJZ1_FV2_test1"; //15-50 1秒加1
String mp3 = "SPF_XFJZ1_FV2_test2"; //15-50 1秒加1
String mp4 = "SPF_XFJZ1_FL2"; //3000-8000 随机
String mp5 = "SPF_XFJZ1_FL2_test1"; //3000-8000 随机
String mp6 = "SPF_XFJZ1_FL2_test2"; //3000-8000 随机
String mp7 = "SPF_XFJZ1_RUN1_test";
RMap<String, Integer> map_list = redissonClient.getMap("test_mpoint");
map_list.fastPutAsync(mp1, 15);
map_list.fastPutAsync(mp2, 15);
map_list.fastPutAsync(mp3, 15);
map_list.fastPutAsync(mp4, 3000);
map_list.fastPutAsync(mp5, 3000);
map_list.fastPutAsync(mp6, 3000);
map_list.fastPutAsync(mp7, 1);
//将推送状态设置为no
RMap<String, String> map_status = redissonClient.getMap("test_mpoint_status");
map_status.fastPutAsync("status", "yes");
return "开始推送" + CommUtil.nowDate();
}
/**
* 演示推送开始
*
* @param request
* @param model
* @return
*/
@RequestMapping("/stopSend.do")
@ResponseBody
public String stopSend(HttpServletRequest request, Model model) {
String mp1 = "SPF_XFJZ1_FV2"; //15-50 1秒加1
String mp2 = "SPF_XFJZ1_FV2_test1"; //15-50 1秒加1
String mp3 = "SPF_XFJZ1_FV2_test2"; //15-50 1秒加1
String mp4 = "SPF_XFJZ1_FL2"; //3000-8000 随机
String mp5 = "SPF_XFJZ1_FL2_test1"; //3000-8000 随机
String mp6 = "SPF_XFJZ1_FL2_test2"; //3000-8000 随机
String mp7 = "SPF_XFJZ1_RUN1_test";
//数据置0
RMap<String, Integer> map_list = redissonClient.getMap("test_mpoint");
map_list.fastPutAsync(mp1, 0);
map_list.fastPutAsync(mp2, 0);
map_list.fastPutAsync(mp3, 0);
map_list.fastPutAsync(mp4, 0);
map_list.fastPutAsync(mp5, 0);
map_list.fastPutAsync(mp6, 0);
map_list.fastPutAsync(mp7, 0);
//推送数据
// mPointService.sendDataTest(map_list);
//将推送状态设置为no
RMap<String, String> map_status = redissonClient.getMap("test_mpoint_status");
map_status.fastPutAsync("status", "no");
return "关闭推送" + CommUtil.nowDate();
}
}

View File

@ -0,0 +1,108 @@
package com.sipai.controller.mqtt;
import com.alibaba.druid.util.StringUtils;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointHistory;
import com.sipai.entity.user.Company;
import com.sipai.service.mqtt.MqttService;
import com.sipai.service.scada.MPointHistoryService;
import com.sipai.service.scada.MPointService;
import com.sipai.service.user.CompanyService;
import com.sipai.tools.CommUtil;
import com.sipai.tools.ConstantString;
import com.sipai.tools.SpringContextUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.Map;
/**
* 通过emqx webHook 获取所有设备的上下线消息 并存生产库 _COM点 如水口MZ_SK11_C_01_COM
* sj 2021-05-24
*/
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/webHook")
public class WebHookController {
@Autowired
private MqttService mqttService;
@PostMapping("/onJkWebHook")
public void onWebHook(@RequestBody Map<String, String> param) {
MPointService mPointService = (MPointService) SpringContextUtil.getBean("mPointService");
MPointHistoryService mPointHistoryService = (MPointHistoryService) SpringContextUtil.getBean("mPointHistoryService");
CompanyService companyService = (CompanyService) SpringContextUtil.getBean("companyService");
String action = MapUtils.getString(param, "action", "");
try {
String dt = "";//时间戳(秒)
String cid = "";//cid截取9位 为厂id
String dtime = "";//时间 (yyyy-MM-dd HH:mm:ss)
int st = 0;
//连接
if ("client_connected".equals(action)) {
cid = MapUtils.getString(param, "client_id", "");
if (StringUtils.isEmpty(cid)) {
cid = MapUtils.getString(param, "clientid", "");
}
dt = MapUtils.getString(param, "connected_at", "");
st = 1;
dtime = CommUtil.stampToDate(dt);
System.out.println("连接cid=" + cid);
}
//断开连接
if ("client_disconnected".equals(action)) {
cid = MapUtils.getString(param, "client_id", "");
if (StringUtils.isEmpty(cid)) {
cid = MapUtils.getString(param, "clientid", "");
}
dt = MapUtils.getString(param, "disconnected_at", "");
st = 0;
dtime = CommUtil.stampToDate(dt);
System.out.println("断开cid=" + cid);
}
String mpId = cid + "_COM";//测量点id
String bizId = cid.substring(0, 9);//厂id
Company company = companyService.selectByPrimaryKey(bizId);
if (company != null) {
bizId = company.getPid();
// MPoint mPoint = mPointService.selectById(bizId, mpId);
MPoint mPoint = mPointService.selectById(bizId,mpId);
if (mPoint != null) {
MPointHistory mPointHistory = new MPointHistory();
//修改主表
mPoint.setId(mPoint.getId());
mPoint.setMeasuredt(dtime);
mPoint.setParmvalue(new BigDecimal(st));
mPointService.update(mPoint);
//插入子表
mPointHistory.setMeasuredt(dtime);
mPointHistory.setParmvalue(new BigDecimal(st));
mPointHistory.setTbName("[tb_mp_" + mpId + "]");
mPointHistoryService.save(bizId, mPointHistory);
//System.out.println(mpId + "执行时间戳:" + CommUtil.stampToDate(dt));
//网关掉线发送至报警服务
System.out.println("设备掉线已推给报警服务(" + mpId + ")" + "----" + st);
mqttService.sentRabbitmq(ConstantString.MQ_ALARM_MQTT, mpId, st + "", dtime);
} else {
System.out.println("点不存在");
}
} else {
System.out.println("厂不存在");
}
} catch (Exception e) {
System.out.println("通讯接口执行失败:" + e);
}
}
}

View File

@ -0,0 +1,96 @@
package com.sipai.controller.opc;
import com.sipai.service.opc.InitOpcUaService;
import com.sipai.service.opc.OpcUaService;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/opcua")
public class OpcUaController {
private final OpcUaService opcUaService;
@Autowired
private InitOpcUaService initOpcUaService;
public OpcUaController(@Autowired(required = false) OpcUaService opcUaService) {
this.opcUaService = opcUaService;
}
/**
* 读取单个OPC UA节点的值
*
* @param nodeId 节点ID格式为ns=2;s=通道 1.设备 1.标记3
* @return 节点值或错误信息
*/
@GetMapping("/read")
public Object readValue(@RequestParam String nodeId) {
if (opcUaService == null) {
return "OPC UA 未启动请检查yml配置文件钟opc: enabled: true";
}
try {
return opcUaService.readNodeValue(nodeId);
} catch (Exception e) {
return "读取值错误: " + e.getMessage();
}
}
/**
* 写入单个OPC UA节点的值
*
* @param nodeId 节点ID格式为ns=2;s=通道 1.设备 1.标记3
* @param value 要写入的值
* @return 写入是否成功或错误信息
*/
@PostMapping("/write")
public String writeValue(@RequestParam String nodeId, @RequestParam Object value) {
if (opcUaService == null) {
return "OPC UA 未启动请检查yml配置文件钟opc: enabled: true";
}
try {
boolean success = opcUaService.writeNodeValue(nodeId, value);
return success ? "写入成功" : "写入失败";
} catch (Exception e) {
return "写入错误: " + e.getMessage();
}
}
/**
* 取消订阅
*
* @param nodeId
* @return
*/
@PostMapping("/unsubscribeFromNode")
public String unsubscribeFromNode(@RequestParam String nodeId) {
if (opcUaService == null) {
return "OPC UA 未启动请检查yml配置文件钟opc: enabled: true";
}
try {
boolean success = opcUaService.unsubscribeFromNode(nodeId);
return success ? "取消成功" : "取消失败";
} catch (Exception e) {
return "取消错误: " + e.getMessage();
}
}
/**
* 同步opcua订阅点位查询es中opcua的采集点位将不需要的点位取消订阅-一般默认1小时会进行一次同步有些点位修改总表或es后可手动调用一次立即同步
*
* @return
*/
@PostMapping("/sysSub")
public String sysSub() {
if (opcUaService == null) {
return "OPC UA 未启动请检查yml配置文件钟opc: enabled: true";
}
initOpcUaService.manualSyncSubscriptions();
return "suc";
}
}

View File

@ -0,0 +1,29 @@
package com.sipai.controller.rabbitmq;
import com.sipai.service.rabbitmq.MQService;
import com.sipai.tools.ConstantString;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/mq")
@Api(value = "/mq", tags = "发送RabbitMQ消息")
public class MQController {
@Autowired
private MQService mQService;
@RequestMapping("sendMQ")
@ApiOperation(value = "发送消息", notes = "发送消息", httpMethod = "POST")
@ApiResponses({@ApiResponse(code = 400, message = "请求参数没填好")})
@ApiImplicitParams({
@ApiImplicitParam(name = "msg", value = "msg", dataType = "String", paramType = "query", example = "YES! PPG", required = true),
})
public String sendMQ(@RequestParam(value = "msg", required = false, defaultValue = "YES! PPG") String msg) {
this.mQService.sendMQ(ConstantString.MQ_ALARM_MQTT, msg);
return "success";
}
}

View File

@ -0,0 +1,114 @@
package com.sipai.controller.scada;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.config.AppConfig;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.user.Company;
import com.sipai.entity.user.User;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.CommString;
import com.sipai.tools.Result;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 你的名字
* @Date: 2021/04/25/21:42
* @Description:
*/
@Controller
@RequestMapping("/mPoint")
public class MPointController {
@Autowired
private MPointService mPointService;
@Autowired
private RedissonClient redissonClient;
@Autowired
private AppConfig appConfig;
@RequestMapping("/update.do")
@ResponseBody
public Integer update(HttpServletRequest request, Model model,
@ModelAttribute("mPoint") MPoint mPoint,
@ModelAttribute("bizid") String bizid) {
return mPointService.update(mPoint);
}
@RequestMapping("/selectById.do")
@ResponseBody
public MPoint selectById(HttpServletRequest request, Model model,
@ModelAttribute(value = "id") String id) {
MPoint mPoint = mPointService.selectById4Es(id);
return mPoint;
}
/**
* 管网平台获取实时数据接口
* @param request
* @param model
* @param mpcode
* @return
*/
@RequestMapping("/getDataByMpCode.do")
@ResponseBody
public Result getDataByMpCode(HttpServletRequest request, Model model,
@ModelAttribute(value = "mpcode") String mpcode) {
JSONArray jsonArray = new JSONArray();
String[] mpcodes = mpcode.split(",");
if (mpcodes != null && mpcodes.length > 0) {
if (mpcodes.length > appConfig.getMaxPoints()) {
Result res = Result.failed("一次最多处理" + appConfig.getMaxPoints() + "个点位");
return res;
} else {
System.out.println("收到点位(" + mpcodes.length + "个):");
}
String ids = "";
for (int i = 0; i < mpcodes.length; i++) {
ids += "'" + mpcodes[i] + "',";
}
ids = ids.substring(0, ids.length() - 1);
Map<String, String> map = new HashMap<>();
List<MPoint> list = mPointService.selectListByWhere("where 1=1 and id in (" + ids + ")");
for (MPoint mPoint : list) {
if (mPoint.getParmvalue() != null && mPoint.getMeasuredt() != null) {
map.put(mPoint.getId(), mPoint.getParmvalue() + ";" + mPoint.getMeasuredt());
}
}
for (int i = 0; i < mpcodes.length; i++) {
if (map.get(mpcodes[i]) != null) {
String[] val = map.get(mpcodes[i]).split(";");
JSONObject jsonObject = new JSONObject();
jsonObject.put("mpcode", mpcodes[i]);
jsonObject.put("parmvalue", val[0]);
jsonObject.put("measuredt", val[1].length() > 19 ? val[1].substring(0, 19) : val[1]);
jsonArray.add(jsonObject);
} else {
JSONObject jsonObject = new JSONObject();
jsonObject.put("mpcode", mpcodes[i]);
jsonObject.put("parmvalue", "");
jsonObject.put("measuredt", "");
jsonArray.add(jsonObject);
}
}
}
Result res = Result.success(jsonArray);
return res;
}
}

View File

@ -0,0 +1,40 @@
package com.sipai.controller.user;
import com.sipai.entity.user.Company;
import com.sipai.service.user.CompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 你的名字
* @Date: 2021/04/25/21:15
* @Description:
*/
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("/save.do")
@ResponseBody
public Integer save(HttpServletRequest request, Model model,
@ModelAttribute("company") Company company) {
return companyService.insert(company);
}
@RequestMapping("/delete.do")
@ResponseBody
public int delete(HttpServletRequest request, Model model,
@ModelAttribute("id") String id) {
return companyService.deleteByPrimaryKey(id);
}
}

View File

@ -0,0 +1,35 @@
package com.sipai.controller.user;
import com.sipai.entity.user.User;
import com.sipai.service.user.UserService;
import com.sipai.tools.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/test1")
@ResponseBody
public Result index(HttpServletRequest request) {
Result result = Result.success(1);
return result;
}
@RequestMapping(value = "/test2")
@ResponseBody
public Result index2(HttpServletRequest request) {
Result result = Result.failed("");
return result;
}
}

View File

@ -0,0 +1,24 @@
package com.sipai.dao.Listener;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.Listener.ListenerHis;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class ListenerHisDao extends CommDaoImpl<ListenerHis> {
public ListenerHisDao() {
super();
this.setMappernamespace("Listener.ListenerHisMapper");
}
public List<ListenerHis> selectTopByWhere(String where) {
ListenerHis listenerHis = new ListenerHis();
listenerHis.setWhere(where);
List<ListenerHis> list = this.getSqlSession().selectList("Listener.ListenerHisMapper.selectTopByWhere", listenerHis);
return list;
}
}

View File

@ -0,0 +1,15 @@
package com.sipai.dao.Listener;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.Listener.ListenerInterface;
import org.springframework.stereotype.Repository;
@Repository
public class ListenerInterfaceDao extends CommDaoImpl<ListenerInterface> {
public ListenerInterfaceDao() {
super();
this.setMappernamespace("Listener.ListenerInterfaceMapper");
}
}

View File

@ -0,0 +1,15 @@
package com.sipai.dao.Listener;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.Listener.ListenerMessage;
import org.springframework.stereotype.Repository;
@Repository
public class ListenerMessageDao extends CommDaoImpl<ListenerMessage> {
public ListenerMessageDao() {
super();
this.setMappernamespace("Listener.ListenerMessageMapper");
}
}

View File

@ -0,0 +1,15 @@
package com.sipai.dao.Listener;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.Listener.ListenerPoint;
import org.springframework.stereotype.Repository;
@Repository
public class ListenerPointDao extends CommDaoImpl<ListenerPoint> {
public ListenerPointDao() {
super();
this.setMappernamespace("Listener.ListenerPointMapper");
}
}

View File

@ -0,0 +1,125 @@
package com.sipai.dao.base;
import java.util.List;
public interface CommDao<T>{
/**====基础的CURD操作====**/
/**
* 根据id查找唯一对象
* @param
* @param t
* @return
*/
public T selectByPrimaryKey(String t);
/**
* 根据id删除唯一对象
* @param
* @param t
* @return
*/
public int deleteByPrimaryKey(String t);
/**
* 根据对象信息插入数据
* @param
* @param t
* @return
*/
public int insert(T t);
/**
* 根据对象信息插入数据只插入不为null的字段,不会影响有默认值的字段
* @param
* @param t
* @return
*/
// public int insertSelective(T t);
/**
* 根据对象信息更新数据只跟新不为null的字段
* @param
* @param t
* @return
*/
public int updateByPrimaryKeySelective(T t);
/**
* 根据对象id信息更新数据只跟新不为null的字段
* @param
* @param t
* @return
*/
// public int updateByPrimaryKey(T t);
/**=====扩展的查询=====**/
/**
* 根据where条件查找唯一对象
* @param
* @param t
* @return
*/
public T selectByWhere(T t);
/**
* 根据where条件查找对象列表
* @param
* @param t
* @return
*/
public List<T> selectList(T t);
/**
* 查找和t某些值相等的对象列表
* @param
* @param t
* @return
*/
/**
* 根据where条件查找对象列表
* @param
* @param t
* @return
*/
public List<T> selectListByWhere(T t);
/**
* 查找和t某些值相等的对象列表
* @param
* @param t
* @return
*/
public List<T> selectListByObj(T t);
/**
* 根据sql语句查找对象列表
* @param
* @param t
* @return
*/
public List<T> selectListBySql(T t);
/**
* 根据sql语句查询唯一字段值
* @param
* @param t
* @return
*/
public Object selectValueBySql(T t);
/**
* 根据where条件删除
* @param
* @param t
*/
public int deleteByWhere(T t);
/**
* 根据where条件更新
* @param
* @param t
*/
public int updateByWhere(T t);
/**
* 执行sql语句 :增,删,改
* @param
* @param t
*/
public int executeSql(T t);
public void commit();
public void close();
}

View File

@ -0,0 +1,151 @@
package com.sipai.dao.base;
import java.math.BigDecimal;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;
@Repository
public class CommDaoImpl<T> implements CommDao<T> {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private SqlSession sqlSession;
private String mappernamespace; // 需要操作的mappernamespace名(也是数据库表名)
private boolean isAuto = true;// 默认自动提交
public CommDaoImpl() {
super();
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public boolean isAuto() {
return isAuto;
}
public void setAuto(boolean isAuto) {
this.isAuto = isAuto;
}
public String getMappernamespace() {
return mappernamespace;
}
public void setMappernamespace(String mappernamespace) {
this.mappernamespace = mappernamespace;
}
public T selectByPrimaryKey(String t){
T o = getSqlSession().selectOne(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return o;
}
/**
* wxp为activiti测试修改
* @param t
* @return
*/
public T selectByID(BigDecimal t){
T o = getSqlSession().selectOne(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return o;
}
public int deleteByPrimaryKey(String t) {
return getSqlSession().delete(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int insert(T t){
return getSqlSession().insert(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int insertSelective(T t){
return getSqlSession().insert(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int updateByPrimaryKeySelective(T t){
return getSqlSession().update(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
// public int updateByPrimaryKey(T t){
// return getSqlSession().update(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
// }
public T selectByWhere( T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
if (list != null && list.size() > 0) {
return list.get(0);
} else {
return null;
}
}
public List<T> selectList(T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return list;
}
public List<T> selectListByWhere( T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return list;
}
public List<T> selectListByObj(T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return list;
}
public List<T> selectListByt( T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return list;
}
public List<T> selectListBySql( T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
return list;
}
public T selectValueBySql( T t) {
List<T> list = getSqlSession().selectList(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
if (list != null && list.size() > 0) {
return list.get(0);
} else {
return null;
}
}
public int deleteByWhere( T t) {
return this.getSqlSession().delete(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int updateByWhere( T t) {
return this.getSqlSession().update(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int executeSql( T t) {
return this.getSqlSession().update(mappernamespace+"."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public void commit() {
if (sqlSession != null)
sqlSession.commit();
}
public SqlSession getSqlSession() {
sqlSession = sqlSession == null ? sqlSessionFactory.openSession(isAuto) : sqlSession;
return sqlSession;
}
public void close() {
if (sqlSession != null)
sqlSession.close();
}
}

View File

@ -0,0 +1,43 @@
package com.sipai.dao.data;
import com.sipai.entity.data.PipeTopicMpoint;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PipeTopicMpointDao {
/**
* 添加管网专题页点位信息
*/
int insert(PipeTopicMpoint pipeTopicMpoint);
/**
* 根据主键删除点位信息
*/
boolean deleteByPrimaryKey(Integer id);
/**
* 批量删除点位信息
*/
int deleteBatchByIds(@Param("list") List<Integer> idList);
/**
* 更新点位信息
*/
boolean updateByPrimaryKeySelective(PipeTopicMpoint pipeTopicMpoint);
/**
* 根据主键获取点位详情
*/
PipeTopicMpoint selectByPrimaryKey(Integer id);
/**
* 根据条件查询点位列表
*/
List<PipeTopicMpoint> selectListByWhere(PipeTopicMpoint pipeTopicMpoint);
}

View File

@ -0,0 +1,47 @@
package com.sipai.dao.data;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.data.PipelineEquipment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PipelineEquipmentDao{
/**
* 添加设备
*/
int insert(PipelineEquipment pipelineEquipment);
/**
* 删除设备
*/
boolean deleteByPrimaryKey(Integer id);
/**
* 多删设备
* @param idList
* @return
*/
int deleteBatchByIds(@Param("list") List<Integer> idList);
/**
* 更新设备信息
*/
boolean updateByPrimaryKeySelective(PipelineEquipment equipment);
/**
* 获取设备详情
*/
PipelineEquipment selectByPrimaryKey(Integer id);
/**
* 获取所有设备列表
*/
List<PipelineEquipment> selectListByWhere(PipelineEquipment equipment);
}

View File

@ -0,0 +1,37 @@
package com.sipai.dao.data;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PipelineEquipmentMpointDao {
/**
* 添加关联信息
*/
boolean insert(PipelineEquipmentMpoint mpoint);
/**
* 删除关联信息
*/
boolean deleteByPrimaryKey(Integer id);
/**
* 更新关联信息
*/
boolean updateByPrimaryKeySelective(PipelineEquipmentMpoint mpoint);
/**
* 获取关联信息详情
*/
PipelineEquipmentMpoint selectByPrimaryKey(Integer id);
/**
* 获取所有关联信息列表
*/
List<PipelineEquipmentMpoint> selectListByWhere(PipelineEquipmentMpoint mpoint);
}

View File

@ -0,0 +1,45 @@
package com.sipai.dao.data;
import com.sipai.entity.data.PipelineMpointLibrary;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PipelineMpointLibraryDao {
/**
* 添加测点库信息
*/
boolean insert(PipelineMpointLibrary mpointLibrary);
/**
* 删除测点库信息
*/
boolean deleteByPrimaryKey(String id);
/**
* 多删测点库信息
* @param idList
* @return
*/
int deleteBatchByIds(@Param("list") List<String> idList);
/**
* 更新测点库信息
*/
boolean updateByPrimaryKeySelective(PipelineMpointLibrary mpointLibrary);
/**
* 获取测点库详情
*/
PipelineMpointLibrary selectByPrimaryKey(String id);
/**
* 获取所有测点库列表
*/
List<PipelineMpointLibrary> selectListByWhere(PipelineMpointLibrary mpointLibrary);
}

View File

@ -0,0 +1,32 @@
package com.sipai.dao.mqtt;
import com.sipai.entity.mqtt.MqttConfig;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 你的名字
* @Date: 2021/03/24/17:14
* @Description:
*/
@Mapper
@Repository
public interface MqttConfigDao {
public abstract MqttConfig selectByPrimaryKey(String id);
public abstract Integer deleteByPrimaryKey(String id);
public abstract Integer insert(MqttConfig entity);
public abstract Integer updateByPrimaryKeySelective(MqttConfig entity);
public abstract List<MqttConfig> selectListByWhere(MqttConfig entity);
public abstract Integer deleteByWhere(String where);
}

View File

@ -0,0 +1,34 @@
package com.sipai.dao.mqtt;
import com.sipai.entity.mqtt.MqttConfigTopic;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 你的名字
* @Date: 2021/03/24/17:55
* @Description:
*/
@Mapper
@Repository
public interface MqttConfigTopicDao {
public abstract MqttConfigTopic selectByPrimaryKey(String id);
public abstract Integer deleteByPrimaryKey(String id);
public abstract Integer insert(MqttConfigTopic entity);
public abstract Integer updateByPrimaryKeySelective(MqttConfigTopic entity);
public abstract List<MqttConfigTopic> selectListByWhere(MqttConfigTopic entity);
public abstract Integer deleteByWhere(String wherestr);
public abstract List<MqttConfigTopic> selectListByPid(String pid);
}

View File

@ -0,0 +1,25 @@
package com.sipai.dao.scada;
import com.sipai.entity.scada.MPointBzw;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface MPointBzwDao {
public abstract MPointBzw selectByPrimaryKey(String id);
public abstract int deleteByPrimaryKey(String id);
public abstract int insert(MPointBzw entity);
public abstract int updateByPrimaryKeySelective(MPointBzw entity);
public abstract List<MPointBzw> selectListByWhere(MPointBzw entity);
public abstract int deleteByWhere(String where);
}

View File

@ -0,0 +1,19 @@
package com.sipai.dao.scada;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.scada.MPoint;
import org.springframework.stereotype.Repository;
@Repository
public class MPointDao extends CommDaoImpl<MPoint> {
public MPointDao() {
super();
this.setMappernamespace("scada.MPointMapper");
}
public int updateValueByKey(MPoint t) {
return getSqlSession().update("scada.MPointMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
}

View File

@ -0,0 +1,64 @@
package com.sipai.dao.scada;
import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.scada.MPointHistory;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Repository
public class MPointHistoryDao extends CommDaoImpl<MPointHistory> {
public MPointHistoryDao() {
super();
this.setMappernamespace("scada.MPointHistoryMapper");
}
public List<MPointHistory> selectListByTableAWhere(String tablename, String wherestr) {
Map<String,String> paramMap=new HashMap<>();
paramMap.put("table",tablename);
paramMap.put("where",wherestr);
List<MPointHistory> list = getSqlSession().selectList("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), paramMap);
return list;
}
public int deleteByTableAWhere(String tablename, String wherestr) {
Map<String,String> paramMap=new HashMap<>();
paramMap.put("table",tablename);
paramMap.put("where",wherestr);
return this.getSqlSession().delete("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), paramMap);
}
public int createTable(String tablename){
Map<String,String> paramMap=new HashMap<>(1);
paramMap.put("table",tablename);
return getSqlSession().update("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), paramMap);
}
public Integer checkTableExist(String tablename){
Map<String,String> paramMap = new HashMap<>(1);
paramMap.put("table",tablename);
return getSqlSession().selectOne("scada.MPointHistoryMapper.checkTableExist", paramMap);
}
public Integer selectCount(MPointHistory t){
return getSqlSession().selectOne("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public int updateByMeasureDt(MPointHistory t) {
return getSqlSession().update("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), t);
}
public List<MPointHistory> selectIndustrialLibrary(String IP,String MPointID, String intv, String sdt,String edt) {
Map<String,String> paramMap=new HashMap<>();
paramMap.put("IP",IP);
paramMap.put("MPointID",MPointID);
paramMap.put("intv",intv);
paramMap.put("sdt",sdt);
paramMap.put("edt",edt);
List<MPointHistory> list = getSqlSession().selectList("scada.MPointHistoryMapper."+Thread.currentThread().getStackTrace()[1].getMethodName(), paramMap);
return list;
}
}

View File

@ -0,0 +1,8 @@
package com.sipai.dao.scada;
import com.sipai.entity.scada.MPoint;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface MPointRepo extends ElasticsearchRepository<MPoint, String>, MPointRepository {
}

View File

@ -0,0 +1,13 @@
package com.sipai.dao.scada;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointES;
import java.util.List;
public interface MPointRepository {
// int updateSelective(MPoint mpoint);
// int updateValue(MPoint mpoint);
void batchInsert(List<MPointES> mPointES);
void batchUpdate(List<MPointES> mPointES);
}

View File

@ -0,0 +1,105 @@
package com.sipai.dao.scada;
import com.google.gson.Gson;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointES;
import com.sipai.tools.CommUtil;
import org.elasticsearch.action.index.IndexRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class MPointRepositoryImpl implements MPointRepository {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
public void batchInsert(List<MPointES> mPointES){
int counter = 0;
//判断index 是否存在
if (!elasticsearchTemplate.indexExists("es_measurepoint")) {
elasticsearchTemplate.createIndex("es_measurepoint");
}
Gson gson = new Gson();
List<IndexQuery> queries = new ArrayList<IndexQuery>();
if(mPointES != null && mPointES.size()>0){
for (MPointES item : mPointES) {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(item.getId().toString());
indexQuery.setSource(gson.toJson(item));
indexQuery.setIndexName("es_measurepoint");
indexQuery.setType("esmeasurepoint");
queries.add(indexQuery);
//分批提交索引
if (counter % 500 == 0) {
elasticsearchTemplate.bulkIndex(queries);
queries.clear();
//System.out.println("bulkIndex counter : " + counter);
}
counter++;
}
}
//不足批的索引最后不要忘记提交
if (queries.size() > 0) {
elasticsearchTemplate.bulkIndex(queries);
}
// elasticsearchTemplate.refresh("es_measurepoint");
}
@Override
public void batchUpdate(List<MPointES> mPointES) {
int counter = 0;
//判断index 是否存在
if (!elasticsearchTemplate.indexExists("es_measurepoint")) {
elasticsearchTemplate.createIndex("es_measurepoint");
}
Gson gson = new Gson();
List<UpdateQuery> queries = new ArrayList<>();
if (mPointES != null && mPointES.size() > 0) {
for (MPointES item : mPointES) {
if (item.getMeasuredt() != null) {
IndexRequest indexRequest = new IndexRequest();
indexRequest.source("measuredt", item.getMeasuredt());
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(item.getId()).withClass(MPoint.class).withIndexRequest(indexRequest).build();
queries.add(updateQuery);
}
if (item.getParmvalue() != null) {
IndexRequest indexRequest = new IndexRequest();
indexRequest.source("parmvalue", item.getParmvalue());
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(item.getId()).withClass(MPoint.class).withIndexRequest(indexRequest).build();
queries.add(updateQuery);
}
//分批提交索引
if (counter % 500 == 0) {
elasticsearchTemplate.bulkUpdate(queries);
queries.clear();
}
counter++;
}
}
//不足批的索引最后不要忘记提交
if (queries.size() > 0) {
elasticsearchTemplate.bulkUpdate(queries);
}
// elasticsearchTemplate.refresh("es_measurepoint");
}
}

View File

@ -0,0 +1,25 @@
package com.sipai.dao.user;
import com.sipai.entity.user.Company;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface CompanyDao {
public abstract Company selectByPrimaryKey(String id);
public abstract Integer deleteByPrimaryKey(String id);
public abstract Integer insert(Company entity);
public abstract Integer updateByPrimaryKeySelective(Company entity);
public abstract List<Company> selectListByWhere(Company entity);
public abstract Integer deleteByWhere(String where);
}

View File

@ -0,0 +1,13 @@
package com.sipai.dao.user;
import com.sipai.entity.user.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface UserDao {
public abstract List<User> listuser2();
}

View File

@ -0,0 +1,56 @@
package com.sipai.entity.Listener;
import com.sipai.entity.base.SQLAdapter;
public class ListenerHis extends SQLAdapter {
private String id;
private String pointid;
private String value;
private String type;
private String insdt;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPointid() {
return pointid;
}
public void setPointid(String pointid) {
this.pointid = pointid;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getInsdt() {
return insdt;
}
public void setInsdt(String insdt) {
this.insdt = insdt;
}
}

View File

@ -0,0 +1,56 @@
package com.sipai.entity.Listener;
import com.sipai.entity.base.SQLAdapter;
public class ListenerInterface extends SQLAdapter {
private String id;
private String name;
private String type;
private String url;
private String port;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
}

View File

@ -0,0 +1,86 @@
package com.sipai.entity.Listener;
import com.sipai.entity.base.SQLAdapter;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.user.Company;
public class ListenerMessage extends SQLAdapter {
private String id;
private String Cmdtype;
private String Objid;
private String Action;
private String insdt;
private MPoint mPoint;
// private ProcessSection processSection;
private Company company;
public MPoint getmPoint() {
return mPoint;
}
public void setmPoint(MPoint mPoint) {
this.mPoint = mPoint;
}
// public ProcessSection getProcessSection() {
// return processSection;
// }
//
// public void setProcessSection(ProcessSection processSection) {
// this.processSection = processSection;
// }
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCmdtype() {
return Cmdtype;
}
public void setCmdtype(String cmdtype) {
Cmdtype = cmdtype;
}
public String getObjid() {
return Objid;
}
public void setObjid(String objid) {
Objid = objid;
}
public String getAction() {
return Action;
}
public void setAction(String action) {
Action = action;
}
public String getInsdt() {
return insdt;
}
public void setInsdt(String insdt) {
this.insdt = insdt;
}
}

View File

@ -0,0 +1,123 @@
package com.sipai.entity.Listener;
import com.sipai.entity.base.SQLAdapter;
public class ListenerPoint extends SQLAdapter {
private String id;
private String intid;
private String name;
private String address;
private String type;
private String mpcode;
private String datatype;
private String unitid;
//逻辑条件
//= 等于
//> 大于
//< 小于
//change 变化
private String logi;
//逻辑条件对应的值
private String logiVal;
//动作 如等于reset 为置0
private String action;
public String getLogiVal() {
return logiVal;
}
public void setLogiVal(String logiVal) {
this.logiVal = logiVal;
}
public String getLogi() {
return logi;
}
public void setLogi(String logi) {
this.logi = logi;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getIntid() {
return intid;
}
public void setIntid(String intid) {
this.intid = intid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMpcode() {
return mpcode;
}
public void setMpcode(String mpcode) {
this.mpcode = mpcode;
}
public String getDatatype() {
return datatype;
}
public void setDatatype(String datatype) {
this.datatype = datatype;
}
public String getUnitid() {
return unitid;
}
public void setUnitid(String unitid) {
this.unitid = unitid;
}
}

View File

@ -0,0 +1,65 @@
package com.sipai.entity.base;
import com.alibaba.fastjson.JSON;
/**
*
* @author WXP
*
*/
public class Result {
public static final int SUCCESS = 1;
public static final int FAILED = 0;
public static final int REPEATED = 2;//重复添加
public Result(){
}
public Result(int code, String message, Object result) {
this.code = code;
this.msg = message;
if (result instanceof String) {
this.result = JSON.parse(result.toString());
}else{
this.result =result;
}
}
public static Result success(Object result,String msg) {
return new Result(SUCCESS, msg, result);
}
public static Result success(Object result) {
return new Result(SUCCESS, "", result);
}
public static Result success() {
return new Result(SUCCESS, "", null);
}
public static Result failed(String msg) {
return new Result(FAILED, msg, null);
}
public int code;
public String msg;
public Object result;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}

View File

@ -0,0 +1,22 @@
package com.sipai.entity.base;
public class SQLAdapter {
private String sql;
private String where;
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public String getWhere() {
return where;
}
public void setWhere(String where) {
this.where = where;
}
}

View File

@ -0,0 +1,37 @@
package com.sipai.entity.common;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* 分页数据封装类
*/
public class PageData<T> {
private long total; // 总记录数
private int pageSize; // 每页大小
private int pageNum; // 当前页码
private int pages; // 总页数
private List<T> list; // 数据列表
public PageData() {}
public PageData(PageInfo<T> pageInfo) {
this.total = pageInfo.getTotal();
this.pageSize = pageInfo.getPageSize();
this.pageNum = pageInfo.getPageNum();
this.pages = pageInfo.getPages();
this.list = pageInfo.getList();
}
// getters and setters
public long getTotal() { return total; }
public void setTotal(long total) { this.total = total; }
public int getPageSize() { return pageSize; }
public void setPageSize(int pageSize) { this.pageSize = pageSize; }
public int getPageNum() { return pageNum; }
public void setPageNum(int pageNum) { this.pageNum = pageNum; }
public int getPages() { return pages; }
public void setPages(int pages) { this.pages = pages; }
public List<T> getList() { return list; }
public void setList(List<T> list) { this.list = list; }
}

View File

@ -0,0 +1,82 @@
package com.sipai.entity.data;
import java.util.List;
/**
* 报文实体类
* 频道数据
*/
public class ChannelData {
private int type; // 类型 1-6
private int channelNumber; // 通道号
private String channelName; // 通道名称 P1, P2等
private int yesterdayFlow; // 昨日流量
private List<Integer> cumulativeFlows; // 累计流量列表
private List<Float> analogValues; // 模拟量数据(类型4)
private Integer qChannelData; // Q通道数据(类型5)
private Integer mChannelData; // M通道数据(类型6)
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getChannelNumber() {
return channelNumber;
}
public void setChannelNumber(int channelNumber) {
this.channelNumber = channelNumber;
}
public String getChannelName() {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
public int getYesterdayFlow() {
return yesterdayFlow;
}
public void setYesterdayFlow(int yesterdayFlow) {
this.yesterdayFlow = yesterdayFlow;
}
public List<Integer> getCumulativeFlows() {
return cumulativeFlows;
}
public void setCumulativeFlows(List<Integer> cumulativeFlows) {
this.cumulativeFlows = cumulativeFlows;
}
public List<Float> getAnalogValues() {
return analogValues;
}
public void setAnalogValues(List<Float> analogValues) {
this.analogValues = analogValues;
}
public Integer getqChannelData() {
return qChannelData;
}
public void setqChannelData(Integer qChannelData) {
this.qChannelData = qChannelData;
}
public Integer getmChannelData() {
return mChannelData;
}
public void setmChannelData(Integer mChannelData) {
this.mChannelData = mChannelData;
}
}

View File

@ -0,0 +1,88 @@
package com.sipai.entity.data;
import java.util.List;
public class DeviceData {
private int stationId;
private String startTime;
private int dataCount;
private int length;
private int intervalMinutes;
private float batteryVoltage;
private String deviceInfo;
private int uploadCount;
private List<SensorData> sensorDataList;
public int getUploadCount() {
return uploadCount;
}
public void setUploadCount(int uploadCount) {
this.uploadCount = uploadCount;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getStationId() {
return stationId;
}
public void setStationId(int stationId) {
this.stationId = stationId;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public int getDataCount() {
return dataCount;
}
public void setDataCount(int dataCount) {
this.dataCount = dataCount;
}
public int getIntervalMinutes() {
return intervalMinutes;
}
public void setIntervalMinutes(int intervalMinutes) {
this.intervalMinutes = intervalMinutes;
}
public float getBatteryVoltage() {
return batteryVoltage;
}
public void setBatteryVoltage(float batteryVoltage) {
this.batteryVoltage = batteryVoltage;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public List<SensorData> getSensorDataList() {
return sensorDataList;
}
public void setSensorDataList(List<SensorData> sensorDataList) {
this.sensorDataList = sensorDataList;
}
}

View File

@ -0,0 +1,131 @@
package com.sipai.entity.data;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
* 报文实体类
* 设备数据分组
*/
public class DeviceDataPacket {
private String startCode; // 起始符 AB CD
private int length; // 长度 0x007D
private int stationId; // 站号 0x0066
private LocalDateTime timestamp; // 年月日时分 11 05 24 16 15
private int dataCount; // 数据个数 0x03
private int interval; // 数据间隔(分钟) 0x15
private float batteryVoltage; // 电池电压 7.18V
private int uploadCount; // 上发次数 5
private int signalStrength; // 信号强度 0x1E
private String deviceInfo; // 设备信息 "D115 1.4 1.0.11"
private List<ChannelData> channelDataList; // 通道数据列表
private int checksum; // 校验和
private String endCode; // 结束符 0D 0A
public String getStartCode() {
return startCode;
}
public void setStartCode(String startCode) {
this.startCode = startCode;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getStationId() {
return stationId;
}
public void setStationId(int stationId) {
this.stationId = stationId;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public int getDataCount() {
return dataCount;
}
public void setDataCount(int dataCount) {
this.dataCount = dataCount;
}
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public float getBatteryVoltage() {
return batteryVoltage;
}
public void setBatteryVoltage(float batteryVoltage) {
this.batteryVoltage = batteryVoltage;
}
public int getUploadCount() {
return uploadCount;
}
public void setUploadCount(int uploadCount) {
this.uploadCount = uploadCount;
}
public int getSignalStrength() {
return signalStrength;
}
public void setSignalStrength(int signalStrength) {
this.signalStrength = signalStrength;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public List<ChannelData> getChannelDataList() {
return channelDataList;
}
public void setChannelDataList(List<ChannelData> channelDataList) {
this.channelDataList = channelDataList;
}
public int getChecksum() {
return checksum;
}
public void setChecksum(int checksum) {
this.checksum = checksum;
}
public String getEndCode() {
return endCode;
}
public void setEndCode(String endCode) {
this.endCode = endCode;
}
}

View File

@ -0,0 +1,28 @@
package com.sipai.entity.data;
import com.sipai.entity.base.SQLAdapter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 管网专题页点位信息实体类
*/
@Data
public class PipeTopicMpoint extends SQLAdapter implements Serializable {
private Integer id; // 自增主键
private String pointName; // 点位名称
private String pointCode; // 点位编号
private String type; // 所属类型
private Integer isConstant; // 是否常量0-否1-是)
private String constantValue; // 常量值
private Integer sortOrder; // 排序序号
@JsonIgnore
private String sql;
@JsonIgnore
private String where;
}

View File

@ -0,0 +1,32 @@
package com.sipai.entity.data;
import com.sipai.entity.base.SQLAdapter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 管道设备实体类
*/
@Data
public class PipelineEquipment extends SQLAdapter implements Serializable {
private Integer id;
private String stationCode;//站点编号
private String equipmentType;//设备类型:井盖、流量计、液位计、电导率、雨量计、内涝监测
private String productModel;//产品型号
private Integer uploadCycle;//上传周期
private String uploadCycleUnit;//上传周期 单位
private String lastUploadTime;//最近一次上传数据时间
private String status; //1在线 0离线 null为未检测
//用于查询对应的name
private String equipmentTypeName;//设备类型:井盖、流量计、液位计、电导率、雨量计、内涝监测
@JsonIgnore
private String sql;
@JsonIgnore
private String where;
}

View File

@ -0,0 +1,25 @@
package com.sipai.entity.data;
import com.sipai.entity.base.SQLAdapter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
/**
* 管道设备与测点关联实体类
*/
@Data
public class PipelineEquipmentMpoint extends SQLAdapter implements Serializable {
private Integer id;
private Integer pid; // 关联 PipelineEquipment 的 id
private String mpcode; // 测点
private String mpname; // 名称
private String tag; // 编码
@JsonIgnore
private String sql;
@JsonIgnore
private String where;
}

View File

@ -0,0 +1,27 @@
package com.sipai.entity.data;
import com.sipai.entity.base.SQLAdapter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
/**
* 管道测点 库(这边维护好,设备那边可以直接导入)
* sj 2025-06-18
*/
@Data
public class PipelineMpointLibrary extends SQLAdapter implements Serializable {
private String id;
private String equipmentType;
private String code;
private String name;
private Integer morder;
// 用于查询对应的name
@JsonIgnore
private String sql;
@JsonIgnore
private String where;
}

View File

@ -0,0 +1,120 @@
package com.sipai.entity.data;
import com.sipai.tools.AlarmType;
import java.util.List;
import java.util.Map;
public class SensorData {
private int type; // 1-脉冲量, 2-开关量, 3-报警量, 4-模拟量, 5-Q通道, 6-M通道
private int channel;
// 脉冲量特有
private long yesterdayFlow;
private List<Long> accumulatedFlows;
private int qValue; // 原始Q通道值
private Map<AlarmType, Boolean> alarmStatus; // 报警状态映射
// 开关量/报警量
private List<Integer> statusList;
// 模拟量
private List<Float> analogValues;
// Q通道
private List<String> qValues;
// M通道
private List<Integer> mValues;
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getChannel() {
return channel;
}
public void setChannel(int channel) {
this.channel = channel;
}
public long getYesterdayFlow() {
return yesterdayFlow;
}
public void setYesterdayFlow(long yesterdayFlow) {
this.yesterdayFlow = yesterdayFlow;
}
public List<Long> getAccumulatedFlows() {
return accumulatedFlows;
}
public void setAccumulatedFlows(List<Long> accumulatedFlows) {
this.accumulatedFlows = accumulatedFlows;
}
public List<Integer> getStatusList() {
return statusList;
}
public void setStatusList(List<Integer> statusList) {
this.statusList = statusList;
}
public List<Float> getAnalogValues() {
return analogValues;
}
public void setAnalogValues(List<Float> analogValues) {
this.analogValues = analogValues;
}
public List<String> getqValues() {
return qValues;
}
public void setqValues(List<String> qValues) {
this.qValues = qValues;
}
public List<Integer> getmValues() {
return mValues;
}
public void setmValues(List<Integer> mValues) {
this.mValues = mValues;
}
public int getqValue() {
return qValue;
}
public void setqValue(int qValue) {
this.qValue = qValue;
}
public Map<AlarmType, Boolean> getAlarmStatus() {
return alarmStatus;
}
public void setAlarmStatus(Map<AlarmType, Boolean> alarmStatus) {
this.alarmStatus = alarmStatus;
}
}

View File

@ -0,0 +1,71 @@
package com.sipai.entity.enums;
public enum DeviceTypeEnum {
// 枚举常量,对应下拉框中的类型
MANHOLE_COVER("井盖", "1"),
FLOW_METER("流量计", "2"),
LIQUID_LEVEL_METER("液位计", "3"),
CONDUCTIVITY("电导率", "4"),
RAIN_GAUGE("雨量计", "5"),
WATERLOGGING_DETECTION("内涝检测", "6");
// 类型名称
private final String typeName;
// 类型编码
private final String typeCode;
/**
* 构造方法
* @param typeName 类型名称
* @param typeCode 类型编码
*/
DeviceTypeEnum(String typeName, String typeCode) {
this.typeName = typeName;
this.typeCode = typeCode;
}
/**
* 获取类型名称
* @return 类型名称
*/
public String getTypeName() {
return typeName;
}
/**
* 获取类型编码
* @return 类型编码
*/
public String getTypeCode() {
return typeCode;
}
// 也可根据需求添加根据名称或编码获取枚举常量的方法,示例如下:
/**
* 根据类型名称获取枚举常量
* @param typeName 类型名称
* @return 对应的枚举常量,若未找到返回 null
*/
public static DeviceTypeEnum getByTypeName(String typeName) {
for (DeviceTypeEnum enumConstant : DeviceTypeEnum.values()) {
if (enumConstant.getTypeName().equals(typeName)) {
return enumConstant;
}
}
return null;
}
/**
* 根据类型编码获取枚举常量
* @param typeCode 类型编码
* @return 对应的枚举常量,若未找到返回 null
*/
public static DeviceTypeEnum getByTypeCode(String typeCode) {
for (DeviceTypeEnum enumConstant : DeviceTypeEnum.values()) {
if (enumConstant.getTypeCode().equals(typeCode)) {
return enumConstant;
}
}
return null;
}
}

View File

@ -0,0 +1,16 @@
package com.sipai.entity.mqtt;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 用于配置emqx的常量 和 提供云平台的一些接口 如指令下发,获取网关在线状态等
* sj 2021-05-27
*/
public class Mqtt {
/*public static String BrokerAddress = "tcp://192.168.10.17:1883";
public static String Dashboard_01 = "http://192.168.10.17:18083";
public static String Username = "admin";
public static String Password = "sipai@64368180";*/
}

View File

@ -0,0 +1,102 @@
package com.sipai.entity.mqtt;
import com.sipai.entity.base.SQLAdapter;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/16:26
* @Description: mqtt配置主表
*/
public class MqttConfig extends SQLAdapter {
private String id;
private String insdt;
private String clientId;
private String clientName;
private String brokerIp;
private String tomcatPort;
private String username;
private String password;
private Integer morder;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getInsdt() {
return insdt;
}
public void setInsdt(String insdt) {
this.insdt = insdt;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public String getBrokerIp() {
return brokerIp;
}
public void setBrokerIp(String brokerIp) {
this.brokerIp = brokerIp;
}
public String getTomcatPort() {
return tomcatPort;
}
public void setTomcatPort(String tomcatPort) {
this.tomcatPort = tomcatPort;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getMorder() {
return morder;
}
public void setMorder(Integer morder) {
this.morder = morder;
}
}

View File

@ -0,0 +1,72 @@
package com.sipai.entity.mqtt;
import com.sipai.entity.base.SQLAdapter;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/16:26
* @Description: mqtt配置副表
*/
public class MqttConfigTopic extends SQLAdapter {
private String id;
private String name;
private String topic;
private String status;
private String pid;
private Integer morder;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic == null ? null : topic.trim();
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status == null ? null : status.trim();
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid == null ? null : pid.trim();
}
public Integer getMorder() {
return morder;
}
public void setMorder(Integer morder) {
this.morder = morder;
}
}

View File

@ -0,0 +1,45 @@
package com.sipai.entity.mqtt;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "mqtt")
public class MqttProperties {
private String brokerAddress; // 对应原 BrokerAddress
private String dashboard01; // 对应原 Dashboard_01
private String username; // 对应原 Username
private String password; // 对应原 Password
public String getBrokerAddress() {
return brokerAddress;
}
public void setBrokerAddress(String brokerAddress) {
this.brokerAddress = brokerAddress;
}
public String getDashboard01() {
return dashboard01;
}
public void setDashboard01(String dashboard01) {
this.dashboard01 = dashboard01;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,608 @@
package com.sipai.entity.scada;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sipai.entity.base.SQLAdapter;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.math.BigDecimal;
@Mapping(mappingPath = "mpoint_search_mapping.json")
@Setting(settingPath = "mpoint_search_setting.json")
@Document(indexName = "es_measurepoint", type = "esmeasurepoint")
@Component
public class MPoint extends SQLAdapter implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7579438089469008076L;
public static String Flag_Enable = "1";
public static String Flag_Disable = "0";
public static String Flag_Sql = "sql";
public static String Flag_Modbus = "modbus";
public static String Flag_LinkData = "link";
public static String Flag_Type_CAL = "CAL";//单元格计算测量点
public static String Flag_Type_KPI = "KPI";//KPI测量<E6B58B>?
public static String Flag_Type_Data = "data";
public static String Flag_Type_Hand = "hand";//手动测量<E6B58B>?
public static String Flag_Type_Auto = "auto";//自动转发测量<E6B58B>?
public static String Flag_BizType_Hand = "Manual";
public static String Flag_BizType_Auto = "auto";//自动转发
private String chineseValue;//测量点<E9878F>? valuemeaning对应的中文<E4B8AD>?
@Id
private String id;
private String mpointid;
private String mpointcode;
private String parmname;
private String unit;
private BigDecimal alarmmax;
private BigDecimal alarmmin;
private BigDecimal parmvalue;
//@Field(type = FieldType.Date)
private String measuredt;
private BigDecimal rate;
private Integer freq;
private String frequnit;
private String signaltype;
@JsonProperty("signaltag")
private String signaltag;
private String ledtype;
private String ledcolor;
private String directtype;
private String bizid;
private String biztype;
private String numtail;
private String prochour;
private String procday;
private String procmonth;
private String showname;
private String exp;
private BigDecimal forcemin;
private BigDecimal forcemax;
private BigDecimal avgmax;
private BigDecimal avgmin;
private String remoteup;
private Integer morder;
private String triggeralarm;
private String confirmalarm;
private BigDecimal flowset;
private String triggercycle;
private BigDecimal cyclemax;
private BigDecimal cyclemin;
private String triggermutation;
private BigDecimal mutationset;
private BigDecimal causeset;
private BigDecimal operateset;
private BigDecimal resultset;
private String triggerequoff;
private String mathop;
private String valuetype;
private String valuemeaning;
private String active;
private String soundalarm;
private String scdtype;
private BigDecimal spanrange;
private String modbusfigid;
private String register;
private String processsectioncode;
private String equipmentid;
@JsonProperty("source_type")
private String sourceType;
@JsonProperty("patrol_type")
private String patrolType;
private String remark;
private Integer alarmLevel;
private String bizname;
private String disname;
private int subscriptionStatus;
public String getChineseValue() {
return chineseValue;
}
public void setChineseValue(String chineseValue) {
this.chineseValue = chineseValue;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMpointid() {
return mpointid;
}
public void setMpointid(String mpointid) {
this.mpointid = mpointid;
}
public String getMpointcode() {
return mpointcode;
}
public void setMpointcode(String mpointcode) {
this.mpointcode = mpointcode;
}
public String getParmname() {
return parmname;
}
public void setParmname(String parmname) {
this.parmname = parmname;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public BigDecimal getAlarmmax() {
return alarmmax;
}
public void setAlarmmax(BigDecimal alarmmax) {
this.alarmmax = alarmmax;
}
public BigDecimal getAlarmmin() {
return alarmmin;
}
public void setAlarmmin(BigDecimal alarmmin) {
this.alarmmin = alarmmin;
}
public BigDecimal getParmvalue() {
return parmvalue;
}
public void setParmvalue(BigDecimal parmvalue) {
this.parmvalue = parmvalue;
}
public String getMeasuredt() {
return measuredt;
}
public void setMeasuredt(String measuredt) {
this.measuredt = measuredt;
}
public BigDecimal getRate() {
return rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
public Integer getFreq() {
return freq;
}
public void setFreq(Integer freq) {
this.freq = freq;
}
public String getFrequnit() {
return frequnit;
}
public void setFrequnit(String frequnit) {
this.frequnit = frequnit;
}
public String getSignaltype() {
return signaltype;
}
public void setSignaltype(String signaltype) {
this.signaltype = signaltype;
}
public String getSignaltag() {
return signaltag;
}
public void setSignaltag(String signaltag) {
this.signaltag = signaltag;
}
public String getLedtype() {
return ledtype;
}
public void setLedtype(String ledtype) {
this.ledtype = ledtype;
}
public String getLedcolor() {
return ledcolor;
}
public void setLedcolor(String ledcolor) {
this.ledcolor = ledcolor;
}
public String getDirecttype() {
return directtype;
}
public void setDirecttype(String directtype) {
this.directtype = directtype;
}
public String getBizid() {
return bizid;
}
public void setBizid(String bizid) {
this.bizid = bizid;
}
public String getBiztype() {
return biztype;
}
public void setBiztype(String biztype) {
this.biztype = biztype;
}
public String getNumtail() {
return numtail;
}
public void setNumtail(String numtail) {
this.numtail = numtail;
}
public String getProchour() {
return prochour;
}
public void setProchour(String prochour) {
this.prochour = prochour;
}
public String getProcday() {
return procday;
}
public void setProcday(String procday) {
this.procday = procday;
}
public String getProcmonth() {
return procmonth;
}
public void setProcmonth(String procmonth) {
this.procmonth = procmonth;
}
public String getShowname() {
return showname;
}
public void setShowname(String showname) {
this.showname = showname;
}
public String getExp() {
return exp;
}
public void setExp(String exp) {
this.exp = exp;
}
public BigDecimal getForcemin() {
return forcemin;
}
public void setForcemin(BigDecimal forcemin) {
this.forcemin = forcemin;
}
public BigDecimal getForcemax() {
return forcemax;
}
public void setForcemax(BigDecimal forcemax) {
this.forcemax = forcemax;
}
public BigDecimal getAvgmax() {
return avgmax;
}
public void setAvgmax(BigDecimal avgmax) {
this.avgmax = avgmax;
}
public BigDecimal getAvgmin() {
return avgmin;
}
public void setAvgmin(BigDecimal avgmin) {
this.avgmin = avgmin;
}
public String getRemoteup() {
return remoteup;
}
public void setRemoteup(String remoteup) {
this.remoteup = remoteup;
}
public Integer getMorder() {
return morder;
}
public void setMorder(Integer morder) {
this.morder = morder;
}
public String getTriggeralarm() {
return triggeralarm;
}
public void setTriggeralarm(String triggeralarm) {
this.triggeralarm = triggeralarm;
}
public String getConfirmalarm() {
return confirmalarm;
}
public void setConfirmalarm(String confirmalarm) {
this.confirmalarm = confirmalarm;
}
public BigDecimal getFlowset() {
return flowset;
}
public void setFlowset(BigDecimal flowset) {
this.flowset = flowset;
}
public String getTriggercycle() {
return triggercycle;
}
public void setTriggercycle(String triggercycle) {
this.triggercycle = triggercycle;
}
public BigDecimal getCyclemax() {
return cyclemax;
}
public void setCyclemax(BigDecimal cyclemax) {
this.cyclemax = cyclemax;
}
public BigDecimal getCyclemin() {
return cyclemin;
}
public void setCyclemin(BigDecimal cyclemin) {
this.cyclemin = cyclemin;
}
public String getTriggermutation() {
return triggermutation;
}
public void setTriggermutation(String triggermutation) {
this.triggermutation = triggermutation;
}
public BigDecimal getMutationset() {
return mutationset;
}
public void setMutationset(BigDecimal mutationset) {
this.mutationset = mutationset;
}
public BigDecimal getCauseset() {
return causeset;
}
public void setCauseset(BigDecimal causeset) {
this.causeset = causeset;
}
public BigDecimal getOperateset() {
return operateset;
}
public void setOperateset(BigDecimal operateset) {
this.operateset = operateset;
}
public BigDecimal getResultset() {
return resultset;
}
public void setResultset(BigDecimal resultset) {
this.resultset = resultset;
}
public String getTriggerequoff() {
return triggerequoff;
}
public void setTriggerequoff(String triggerequoff) {
this.triggerequoff = triggerequoff;
}
public String getMathop() {
return mathop;
}
public void setMathop(String mathop) {
this.mathop = mathop;
}
public String getValuetype() {
return valuetype;
}
public void setValuetype(String valuetype) {
this.valuetype = valuetype;
}
public String getValuemeaning() {
return valuemeaning;
}
public void setValuemeaning(String valuemeaning) {
this.valuemeaning = valuemeaning;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public String getSoundalarm() {
return soundalarm;
}
public void setSoundalarm(String soundalarm) {
this.soundalarm = soundalarm;
}
public String getScdtype() {
return scdtype;
}
public void setScdtype(String scdtype) {
this.scdtype = scdtype;
}
public BigDecimal getSpanrange() {
return spanrange;
}
public void setSpanrange(BigDecimal spanrange) {
this.spanrange = spanrange;
}
public String getModbusfigid() {
return modbusfigid;
}
public void setModbusfigid(String modbusfigid) {
this.modbusfigid = modbusfigid;
}
public String getRegister() {
return register;
}
public void setRegister(String register) {
this.register = register;
}
public String getProcesssectioncode() {
return processsectioncode;
}
public void setProcesssectioncode(String processsectioncode) {
this.processsectioncode = processsectioncode;
}
public String getEquipmentid() {
return equipmentid;
}
public void setEquipmentid(String equipmentid) {
this.equipmentid = equipmentid;
}
public String getSourceType() {
return sourceType;
}
public void setSourceType(String sourceType) {
this.sourceType = sourceType;
}
public String getPatrolType() {
return patrolType;
}
public void setPatrolType(String patrolType) {
this.patrolType = patrolType;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getAlarmLevel() {
return alarmLevel;
}
public void setAlarmLevel(Integer alarmLevel) {
this.alarmLevel = alarmLevel;
}
public String getBizname() {
return bizname;
}
public void setBizname(String bizname) {
this.bizname = bizname;
}
public String getDisname() {
return disname;
}
public void setDisname(String disname) {
this.disname = disname;
}
public int getSubscriptionStatus() {
return subscriptionStatus;
}
public void setSubscriptionStatus(int subscriptionStatus) {
this.subscriptionStatus = subscriptionStatus;
}
}

View File

@ -0,0 +1,57 @@
package com.sipai.entity.scada;
import com.sipai.entity.base.SQLAdapter;
import java.io.Serializable;
/**
* 测点标识对照表实体类
*/
public class MPointBzw extends SQLAdapter implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 测点ID
*/
private String mpointId;
/**
* 测点标识ID
*/
private String mpointbzwId;
// 无参构造器
public MPointBzw() {
}
// 全参构造器
public MPointBzw(String mpointId, String mpointbzwId) {
this.mpointId = mpointId;
this.mpointbzwId = mpointbzwId;
}
// Getters and Setters
public String getMpointId() {
return mpointId;
}
public void setMpointId(String mpointId) {
this.mpointId = mpointId;
}
public String getMpointbzwId() {
return mpointbzwId;
}
public void setMpointbzwId(String mpointbzwId) {
this.mpointbzwId = mpointbzwId;
}
@Override
public String toString() {
return "MPointBzw{" +
"mpointId='" + mpointId + '\'' +
", mpointbzwId='" + mpointbzwId + '\'' +
'}';
}
}

View File

@ -0,0 +1,42 @@
package com.sipai.entity.scada;
import com.alibaba.fastjson.JSON;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class MPointES extends MPoint {
private static final long serialVersionUID = -4222932639259909065L;
private String source_type;
public String getSource_type() {
return source_type;
}
public void setSource_type(String source_type) {
this.source_type = source_type;
}
public static MPointES format(MPoint mPoint) {
String str = JSON.toJSONString(mPoint);
MPointES mPointES = JSON.parseObject(str, MPointES.class);
mPointES.setSource_type(mPoint.getSourceType());
//时间格式处理
DateTimeFormatter dfES = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
DateTimeFormatter dfSQL = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if (mPoint.getMeasuredt() != null) {
try {
LocalDateTime confirmTime = LocalDateTime.parse(mPoint.getMeasuredt().substring(0, 19), dfSQL);
String confirmTimeStr = dfES.format(confirmTime);
mPointES.setMeasuredt(confirmTimeStr);
} catch (Exception e) {
}
}
return mPointES;
}
}

View File

@ -0,0 +1,154 @@
package com.sipai.entity.scada;
import com.sipai.entity.base.SQLAdapter;
import java.io.Serializable;
import java.math.BigDecimal;
public class MPointHistory extends SQLAdapter implements Serializable{
/**
*
*/
private static final long serialVersionUID = 4552977217414444717L;
private Long itemid;
private BigDecimal parmvalue;
private String measuredt;
private String memotype;
private String memo;
private String userid;
private String insdt;
private String tbName;
private short tag;//标志位值
//为报表展示使用 CPELM
private String year;
private String month;
private String day;
private String hour;
private String min;
public short getTag() {
return tag;
}
public void setTag(short tag) {
this.tag = tag;
}
public Long getItemid() {
return itemid;
}
public void setItemid(Long itemid) {
this.itemid = itemid;
}
public BigDecimal getParmvalue() {
return parmvalue;
}
public void setParmvalue(BigDecimal parmvalue) {
this.parmvalue = parmvalue;
}
public String getMeasuredt() {
return measuredt;
}
public void setMeasuredt(String measuredt) {
this.measuredt = measuredt;
}
public String getMemotype() {
return memotype;
}
public void setMemotype(String memotype) {
this.memotype = memotype;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getInsdt() {
return insdt;
}
public void setInsdt(String insdt) {
this.insdt = insdt;
}
public String getTbName() {
return tbName;
}
public void setTbName(String tbName) {
this.tbName = tbName;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getHour() {
return hour;
}
public void setHour(String hour) {
this.hour = hour;
}
public String getMin() {
return min;
}
public void setMin(String min) {
this.min = min;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}

View File

@ -0,0 +1,201 @@
package com.sipai.entity.user;
import com.sipai.entity.base.SQLAdapter;
import java.math.BigDecimal;
/**
* 公司表
*/
public class Company extends SQLAdapter {
private String id;
private String name;
private String pid;
private String address;
private String tel;
private String website;
private String taskid;
private String post;
private String insdt;
private String insuser;
private Integer version;
private Integer morder;
private String sname;
private String active;
private String type;
private String ename;
private BigDecimal longitude;
private BigDecimal latitude;
private String isCount;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getTaskid() {
return taskid;
}
public void setTaskid(String taskid) {
this.taskid = taskid;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public String getInsdt() {
return insdt;
}
public void setInsdt(String insdt) {
this.insdt = insdt;
}
public String getInsuser() {
return insuser;
}
public void setInsuser(String insuser) {
this.insuser = insuser;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Integer getMorder() {
return morder;
}
public void setMorder(Integer morder) {
this.morder = morder;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public BigDecimal getLongitude() {
return longitude;
}
public void setLongitude(BigDecimal longitude) {
this.longitude = longitude;
}
public BigDecimal getLatitude() {
return latitude;
}
public void setLatitude(BigDecimal latitude) {
this.latitude = latitude;
}
public String getIsCount() {
return isCount;
}
public void setIsCount(String isCount) {
this.isCount = isCount;
}
}

View File

@ -0,0 +1,36 @@
package com.sipai.entity.user;
import com.sipai.entity.base.SQLAdapter;
/**
* 人员表
*/
public class User extends SQLAdapter {
private String id;
private String userName;
private String passWord;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
}

View File

@ -0,0 +1,73 @@
package com.sipai.schedule;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointHistory;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.service.opc.InitOpcUaService;
import com.sipai.service.scada.MPointHistoryService;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.CommUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 定时将总表数据插入到子表
*/
@Service
public class DataSynJob {
@Autowired
private MPointService mPointService;
@Autowired
private MPointHistoryService mPointHistoryService;
@Autowired
private MqttConfigService mqttConfigService;
@Autowired
private InitOpcUaService initOpcUaService;
//定时器yml配置是否启动
@Value("${scheduled.enabled:true}")
private boolean scheduledEnabled;
// @Scheduled(fixedRate = 3600000) // 同步一次opcua的订阅
public void syncSubscriptions() {
initOpcUaService.manualSyncSubscriptions();
}
@Async
@Scheduled(initialDelay = 10000, fixedRate = 600000)//自动订阅mqtt
public void job1() {
if (!scheduledEnabled) return; // 手动拦截
System.out.println("自动订阅========" + CommUtil.nowDate());
mqttConfigService.connect("1");
}
@Async
// @Scheduled(cron = "0 0/3 * * * ?")//数据转发
public void job2() {
if (!scheduledEnabled) return; // 手动拦截
String addstr = "zhuanfa";
System.out.println("开始定时器-----------------" + CommUtil.nowDate() + "-----------------" + addstr);
List<MPoint> list2 = this.mPointService.selectListByWhere("where bizid = '0791CNWS' and SignalType='AI' and MeasureDT>DATE_SUB(NOW(), INTERVAL 5 MINUTE) and source_type='auto' ");
if (list2 != null && list2.size() > 0) {
for (int j = 0; j < list2.size(); ++j) {
MPointHistory mPointHistory = new MPointHistory();
mPointHistory.setParmvalue(list2.get(j).getParmvalue());
mPointHistory.setMeasuredt(list2.get(j).getMeasuredt());
mPointHistory.setTbName(list2.get(j).getMpointcode());
mPointHistory.setUserid("data_job");
mPointHistory.setInsdt(CommUtil.nowDate());
mPointHistoryService.saveByCreate(list2.get(j).getBizid(), mPointHistory);
}
System.out.println("完成一次(有数据)转发,执行了" + list2.size() + "次点");
} else {
System.out.println("完成一次(无数据)转发,执行了" + 0 + "次点");
}
System.out.println("结束定时器-----------------" + CommUtil.nowDate());
}
}

View File

@ -0,0 +1,23 @@
package com.sipai.service.Listener;
import com.sipai.entity.Listener.ListenerHis;
import java.util.List;
public interface ListenerHisService {
public abstract ListenerHis selectById(String id);
public abstract int deleteById(String id);
public abstract int save(ListenerHis entity);
public abstract int update(ListenerHis entity);
public abstract List<ListenerHis> selectListByWhere(String wherestr);
public abstract int deleteByWhere(String wherestr);
public abstract List<ListenerHis> selectTopByWhere(String wherestr);
}

View File

@ -0,0 +1,22 @@
package com.sipai.service.Listener;
import com.sipai.entity.Listener.ListenerInterface;
import java.util.List;
public interface ListenerInterfaceService {
public abstract ListenerInterface selectById(String id);
public abstract int deleteById(String id);
public abstract int save(ListenerInterface entity);
public abstract int update(ListenerInterface entity);
public abstract List<ListenerInterface> selectListByWhere(String wherestr);
public abstract int deleteByWhere(String wherestr);
}

View File

@ -0,0 +1,24 @@
package com.sipai.service.Listener;
import com.sipai.entity.Listener.ListenerMessage;
import java.util.List;
public interface ListenerMessageService {
public abstract ListenerMessage selectById(String id);
public abstract int deleteById(String id);
public abstract int save(ListenerMessage entity);
public abstract int update(ListenerMessage entity);
public abstract List<ListenerMessage> selectListByWhere(String wherestr);
//带入设备编号查询
public abstract List<ListenerMessage> selectListByWhere4Equ(String wherestr, String equipmentId);
public abstract int deleteByWhere(String wherestr);
}

View File

@ -0,0 +1,22 @@
package com.sipai.service.Listener;
import com.sipai.entity.Listener.ListenerPoint;
import java.util.List;
public interface ListenerPointService {
public abstract ListenerPoint selectById(String id);
public abstract int deleteById(String id);
public abstract int save(ListenerPoint entity);
public abstract int update(ListenerPoint entity);
public abstract List<ListenerPoint> selectListByWhere(String wherestr);
public abstract int deleteByWhere(String wherestr);
}

View File

@ -0,0 +1,62 @@
package com.sipai.service.Listener.impl;
import com.sipai.dao.Listener.ListenerHisDao;
import com.sipai.entity.Listener.ListenerHis;
import com.sipai.service.Listener.ListenerHisService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("listenerHisService")
public class ListenerHisServiceImpl implements ListenerHisService {
@Resource
public ListenerHisDao listenerHisDao;
@Override
public ListenerHis selectById(String id) {
ListenerHis listenerHis = listenerHisDao.selectByPrimaryKey(id);
return listenerHis;
}
@Override
public int deleteById(String id) {
int i = listenerHisDao.deleteByPrimaryKey(id);
return i;
}
@Override
public int save(ListenerHis entity) {
int insert = listenerHisDao.insert(entity);
return insert;
}
@Override
public int update(ListenerHis entity) {
int i = listenerHisDao.updateByPrimaryKeySelective(entity);
return i;
}
@Override
public List<ListenerHis> selectListByWhere(String wherestr) {
ListenerHis listenerHis = new ListenerHis();
listenerHis.setWhere(wherestr);
List<ListenerHis> listenerHiss = listenerHisDao.selectListByWhere(listenerHis);
return listenerHiss;
}
@Override
public int deleteByWhere(String wherestr) {
ListenerHis listenerHis = new ListenerHis();
listenerHis.setWhere(wherestr);
int i = listenerHisDao.deleteByWhere(listenerHis);
return i;
}
@Override
public List<ListenerHis> selectTopByWhere(String wherestr) {
List<ListenerHis> listenerHis = listenerHisDao.selectTopByWhere(wherestr);
return listenerHis;
}
}

View File

@ -0,0 +1,56 @@
package com.sipai.service.Listener.impl;
import com.sipai.dao.Listener.ListenerInterfaceDao;
import com.sipai.entity.Listener.ListenerInterface;
import com.sipai.service.Listener.ListenerInterfaceService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("listenerInterfaceService")
public class ListenerInterfaceServiceImpl implements ListenerInterfaceService {
@Resource
public ListenerInterfaceDao listenerInterfaceDao;
@Override
public ListenerInterface selectById(String id) {
ListenerInterface listenerInterface = listenerInterfaceDao.selectByPrimaryKey(id);
return listenerInterface;
}
@Override
public int deleteById(String id) {
int i = listenerInterfaceDao.deleteByPrimaryKey(id);
return i;
}
@Override
public int save(ListenerInterface entity) {
int insert = listenerInterfaceDao.insert(entity);
return insert;
}
@Override
public int update(ListenerInterface entity) {
int i = listenerInterfaceDao.updateByPrimaryKeySelective(entity);
return i;
}
@Override
public List<ListenerInterface> selectListByWhere(String wherestr) {
ListenerInterface listenerInterface = new ListenerInterface();
listenerInterface.setWhere(wherestr);
List<ListenerInterface> listenerInterfaces = listenerInterfaceDao.selectListByWhere(listenerInterface);
return listenerInterfaces;
}
@Override
public int deleteByWhere(String wherestr) {
ListenerInterface listenerInterface = new ListenerInterface();
listenerInterface.setWhere(wherestr);
int i = listenerInterfaceDao.deleteByWhere(listenerInterface);
return i;
}
}

View File

@ -0,0 +1,96 @@
package com.sipai.service.Listener.impl;
import com.sipai.dao.Listener.ListenerMessageDao;
import com.sipai.entity.Listener.ListenerMessage;
import com.sipai.service.Listener.ListenerMessageService;
import com.sipai.service.scada.MPointService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Service("listenerMessageService")
public class ListenerMessageServiceImpl implements ListenerMessageService {
@Resource
ListenerMessageDao listenerMessageDao;
// @Resource
// private CompanyService companyService;
// @Resource
// private ProcessSectionService processSectionService;
@Resource
private MPointService mPointService;
@Override
public ListenerMessage selectById(String id) {
ListenerMessage listenerMessage = listenerMessageDao.selectByPrimaryKey(id);
return listenerMessage;
}
@Override
public int deleteById(String id) {
int i = listenerMessageDao.deleteByPrimaryKey(id);
return i;
}
@Override
public int save(ListenerMessage entity) {
int insert = listenerMessageDao.insert(entity);
return insert;
}
@Override
public int update(ListenerMessage entity) {
int i = listenerMessageDao.updateByPrimaryKeySelective(entity);
return i;
}
@Override
public List<ListenerMessage> selectListByWhere(String wherestr) {
ListenerMessage listenerMessage = new ListenerMessage();
listenerMessage.setWhere(wherestr);
List<ListenerMessage> listenerMessages = listenerMessageDao.selectListByWhere(listenerMessage);
for (ListenerMessage entity : listenerMessages) {
// MPoint mPoint = mPointService.selectById(entity.getObjid());
// if (mPoint != null) {
// entity.setmPoint(mPoint);
// Company company = companyService.selectByPrimaryKey(mPoint.getBizid());
// entity.setCompany(company);
// }
}
return listenerMessages;
}
@Override
public List<ListenerMessage> selectListByWhere4Equ(String wherestr, String equipmentId) {
ListenerMessage listenerMessage = new ListenerMessage();
listenerMessage.setWhere(wherestr);
List<ListenerMessage> listenerMessages = listenerMessageDao.selectListByWhere(listenerMessage);
List<ListenerMessage> listenerMessages2 = new ArrayList<>();
for (int i = 0; i < listenerMessages.size(); i++) {
// MPoint mPoint = mPointService.selectById(listenerMessages.get(i).getObjid());
// if (mPoint != null && mPoint.getEquipmentid().equals(equipmentId)) {
// listenerMessages2.add(listenerMessages.get(i));
// }
}
for (ListenerMessage entity : listenerMessages2) {
// MPoint mPoint = mPointService.selectById(entity.getObjid());
// if (mPoint != null) {
// entity.setmPoint(mPoint);
// Company company = companyService.selectByPrimaryKey(mPoint.getBizid());
// entity.setCompany(company);
// }
}
return listenerMessages2;
}
@Override
public int deleteByWhere(String wherestr) {
ListenerMessage listenerMessage = new ListenerMessage();
listenerMessage.setWhere(wherestr);
int i = listenerMessageDao.deleteByWhere(listenerMessage);
return i;
}
}

View File

@ -0,0 +1,57 @@
package com.sipai.service.Listener.impl;
import com.sipai.dao.Listener.ListenerPointDao;
import com.sipai.entity.Listener.ListenerPoint;
import com.sipai.service.Listener.ListenerPointService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("listenerPointService")
public class ListenerPointServiceImpl implements ListenerPointService {
@Resource
ListenerPointDao listenerPointDao;
@Override
public ListenerPoint selectById(String id) {
ListenerPoint listenerPoint = listenerPointDao.selectByPrimaryKey(id);
return listenerPoint;
}
@Override
public int deleteById(String id) {
int i = listenerPointDao.deleteByPrimaryKey(id);
return i;
}
@Override
public int save(ListenerPoint entity) {
int insert = listenerPointDao.insert(entity);
return insert;
}
@Override
public int update(ListenerPoint entity) {
int i = listenerPointDao.updateByPrimaryKeySelective(entity);
return i;
}
@Override
public List<ListenerPoint> selectListByWhere(String wherestr) {
ListenerPoint listenerPoint = new ListenerPoint();
listenerPoint.setWhere(wherestr);
List<ListenerPoint> listenerPoints = listenerPointDao.selectListByWhere(listenerPoint);
return listenerPoints;
}
@Override
public int deleteByWhere(String wherestr) {
ListenerPoint listenerPoint = new ListenerPoint();
listenerPoint.setWhere(wherestr);
int i = listenerPointDao.deleteByWhere(listenerPoint);
return i;
}
}

View File

@ -0,0 +1,126 @@
package com.sipai.service.data;
import com.sipai.entity.data.ChannelData;
import com.sipai.entity.data.DeviceDataPacket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class DeviceDataParser {
public static DeviceDataPacket parse(byte[] data) {
ByteBuffer buffer = ByteBuffer.wrap(data);
buffer.order(ByteOrder.LITTLE_ENDIAN); // 设置为低位在前
// 1. 验证起始符
if (buffer.get() != (byte) 0xAB || buffer.get() != (byte) 0xCD) {
throw new IllegalArgumentException("Invalid start code (expected AB CD)");
}
DeviceDataPacket packet = new DeviceDataPacket();
packet.setStartCode("ABCD");
// 2. 解析固定字段
packet.setLength(buffer.getShort() & 0xFFFF); // 长度
packet.setStationId(buffer.getShort() & 0xFFFF); // 站号
// 3. 解析时间戳BCD码年(1)月(1)日(1)时(1)分(1)
byte[] timeBytes = new byte[5];
buffer.get(timeBytes);
packet.setTimestamp(LocalDateTime.of(
2000 + bcdToInt(timeBytes[0]), // 年
bcdToInt(timeBytes[1]), // 月
bcdToInt(timeBytes[2]), // 日
bcdToInt(timeBytes[3]), // 时
bcdToInt(timeBytes[4]) // 分
));
// 4. 解析其他字段
packet.setDataCount(buffer.get() & 0xFF); // 数据个数
packet.setInterval(buffer.get() & 0xFF); // 间隔(分钟)
packet.setBatteryVoltage((buffer.getShort() & 0xFFFF) / 100.0f); // 电池电压
packet.setUploadCount(buffer.getShort() & 0xFFFF); // 上发次数
packet.setSignalStrength(buffer.get() & 0xFF); // 信号强度
// 5. 解析设备信息20字节ASCII
byte[] deviceInfoBytes = new byte[20];
buffer.get(deviceInfoBytes);
packet.setDeviceInfo(new String(deviceInfoBytes).trim());
// 跳过保留字段8字节
buffer.position(buffer.position() + 8);
// 6. 解析通道数据
List<ChannelData> channelDataList = new ArrayList<>();
while (buffer.remaining() > 3) { // 至少需要3字节校验和+结束符)
ChannelData channelData = parseChannelData(buffer, packet.getDataCount());
channelDataList.add(channelData);
}
packet.setChannelDataList(channelDataList);
// 7. 校验和与结束符
if (buffer.remaining() >= 1) {
packet.setChecksum(buffer.get() & 0xFF);
}
if (buffer.remaining() >= 2) {
packet.setEndCode(String.format("%02X%02X", buffer.get(), buffer.get()));
}
return packet;
}
private static ChannelData parseChannelData(ByteBuffer buffer, int dataCount) {
ChannelData channelData = new ChannelData();
channelData.setType(buffer.get() & 0xFF); // 类型
channelData.setChannelNumber(buffer.get() & 0xFF); // 通道号
// 修复channelName乱码直接转为HEX字符串
byte[] nameBytes = new byte[]{buffer.get(), buffer.get()};
channelData.setChannelName(String.format("%02X%02X", nameBytes[0], nameBytes[1]));
// 根据类型解析数据
switch (channelData.getType()) {
case 1: // 脉冲量
case 2: // 开关量
case 3: // 报警量
channelData.setYesterdayFlow(buffer.getInt());
channelData.setCumulativeFlows(parseIntList(buffer, dataCount));
break;
case 4: // 模拟量
channelData.setYesterdayFlow(buffer.getInt());
channelData.setAnalogValues(parseFloatList(buffer, dataCount));
break;
case 5: // 虚拟Q通道
channelData.setqChannelData(buffer.getShort() & 0xFFFF);
break;
case 6: // 虚拟M通道
channelData.setmChannelData(buffer.getInt());
break;
}
return channelData;
}
private static List<Integer> parseIntList(ByteBuffer buffer, int count) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < count && buffer.remaining() >= 4; i++) {
list.add(buffer.getInt());
}
return list;
}
private static List<Float> parseFloatList(ByteBuffer buffer, int count) {
List<Float> list = new ArrayList<>();
for (int i = 0; i < count && buffer.remaining() >= 4; i++) {
list.add(buffer.getFloat());
}
return list;
}
private static int bcdToInt(byte b) {
return ((b >> 4) & 0xF) * 10 + (b & 0xF);
}
}

View File

@ -0,0 +1,41 @@
package com.sipai.service.data;
import com.sipai.entity.data.PipeTopicMpoint;
import java.util.List;
/**
* 管网专题页点位服务接口
*/
public interface PipeTopicMpointService {
/**
* 添加点位信息
*/
int insert(PipeTopicMpoint pipeTopicMpoint);
/**
* 根据主键删除点位
*/
boolean delete(Integer id);
/**
* 批量删除点位
*/
boolean deleteBatch(List<Integer> idList);
/**
* 更新点位信息
*/
boolean update(PipeTopicMpoint pipeTopicMpoint);
/**
* 根据主键获取点位详情
*/
PipeTopicMpoint selectByPrimaryKey(Integer id);
/**
* 根据条件查询点位列表
*/
List<PipeTopicMpoint> selectListByWhere(String where);
}

View File

@ -0,0 +1,35 @@
package com.sipai.service.data;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import java.util.List;
/**
* 管道设备与测点关联服务接口
*/
public interface PipelineEquipmentMpointService {
/**
* 添加关联信息
*/
boolean insert(PipelineEquipmentMpoint mpoint);
/**
* 删除关联信息
*/
boolean delete(Integer id);
/**
* 更新关联信息
*/
boolean update(PipelineEquipmentMpoint mpoint);
/**
* 获取关联信息详情
*/
PipelineEquipmentMpoint selectByPrimaryKey(Integer id);
/**
* 获取所有关联信息列表
*/
List<PipelineEquipmentMpoint> selectListByWhere(String where);
}

View File

@ -0,0 +1,60 @@
package com.sipai.service.data;
import com.sipai.entity.data.PipelineEquipment;
import java.util.List;
/**
* 管道设备服务接口
*/
public interface PipelineEquipmentService {
/**
* 添加设备
*/
int insert(PipelineEquipment pipelineEquipment);
/**
* 删除设备
*/
boolean delete(Integer id);
/**
* 更新设备信息
*/
boolean update(PipelineEquipment equipment);
/**
* 获取设备详情
*/
PipelineEquipment selectByPrimaryKey(Integer id);
/**
* 获取所有设备列表
*/
List<PipelineEquipment> selectListByWhere(String where);
/**
* 根据站点编号查询设备
*/
/*List<PipelineEquipment> getEquipmentByStation(String stationCode);
*//**
* 根据设备类型查询设备
*//*
List<PipelineEquipment> getEquipmentByType(String equipmentType);
*//**
* 根据状态查询设备
*//*
List<PipelineEquipment> getEquipmentByStatus(String status);*/
/**
* 更新设备状态
*/
// boolean updateEquipmentStatus(String id, String status);
/**
* 更新设备最后上传时间
*/
// boolean updateLastUploadTime(String id);
}

View File

@ -0,0 +1,42 @@
package com.sipai.service.data;
import com.sipai.entity.data.PipelineMpointLibrary;
import java.util.List;
/**
* 管道测点库服务接口
*/
public interface PipelineMpointLibraryService {
/**
* 添加测点库信息
*/
boolean insert(PipelineMpointLibrary mpointLibrary);
/**
* 删除测点库信息
*/
boolean delete(String id);
/**
* 多删测点库信息
* @param idList
* @return
*/
int deleteBatch(List<String> idList);
/**
* 更新测点库信息
*/
boolean update(PipelineMpointLibrary mpointLibrary);
/**
* 获取测点库详情
*/
PipelineMpointLibrary selectByPrimaryKey(String id);
/**
* 获取所有测点库列表
*/
List<PipelineMpointLibrary> selectListByWhere(String where);
}

View File

@ -0,0 +1,59 @@
package com.sipai.service.data.impl;
import com.sipai.dao.data.PipeTopicMpointDao;
import com.sipai.entity.data.PipeTopicMpoint;
import com.sipai.service.data.PipeTopicMpointService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class PipeTopicMpointServiceImpl implements PipeTopicMpointService {
@Autowired
private PipeTopicMpointDao pipeTopicMpointDao;
public PipeTopicMpointServiceImpl(PipeTopicMpointDao pipeTopicMpointDao) {
this.pipeTopicMpointDao = pipeTopicMpointDao;
}
@Override
public int insert(PipeTopicMpoint pipeTopicMpoint) {
return pipeTopicMpointDao.insert(pipeTopicMpoint);
}
@Override
public boolean delete(Integer id) {
return pipeTopicMpointDao.deleteByPrimaryKey(id);
}
@Override
public boolean deleteBatch(List<Integer> idList) {
if (CollectionUtils.isEmpty(idList)) {
return false;
}
int count = pipeTopicMpointDao.deleteBatchByIds(idList);
return count > 0;
}
@Override
public boolean update(PipeTopicMpoint pipeTopicMpoint) {
return pipeTopicMpointDao.updateByPrimaryKeySelective(pipeTopicMpoint);
}
@Override
public PipeTopicMpoint selectByPrimaryKey(Integer id) {
return pipeTopicMpointDao.selectByPrimaryKey(id);
}
@Override
public List<PipeTopicMpoint> selectListByWhere(String where) {
PipeTopicMpoint pipeTopicMpoint = new PipeTopicMpoint();
pipeTopicMpoint.setWhere(where);
return pipeTopicMpointDao.selectListByWhere(pipeTopicMpoint);
}
}

View File

@ -0,0 +1,48 @@
package com.sipai.service.data.impl;
import com.sipai.dao.data.PipelineEquipmentMpointDao;
import com.sipai.entity.data.PipelineEquipmentMpoint;
import com.sipai.service.data.PipelineEquipmentMpointService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class PipelineEquipmentMpointServiceImpl implements PipelineEquipmentMpointService {
@Autowired
private PipelineEquipmentMpointDao pipelineEquipmentMpointDao;
public PipelineEquipmentMpointServiceImpl(PipelineEquipmentMpointDao mpointDao) {
this.pipelineEquipmentMpointDao = mpointDao;
}
@Override
public boolean insert(PipelineEquipmentMpoint mpoint) {
return pipelineEquipmentMpointDao.insert(mpoint);
}
@Override
public boolean delete(Integer id) {
return pipelineEquipmentMpointDao.deleteByPrimaryKey(id);
}
@Override
public boolean update(PipelineEquipmentMpoint mpoint) {
return pipelineEquipmentMpointDao.updateByPrimaryKeySelective(mpoint);
}
@Override
public PipelineEquipmentMpoint selectByPrimaryKey(Integer id) {
return pipelineEquipmentMpointDao.selectByPrimaryKey(id);
}
@Override
public List<PipelineEquipmentMpoint> selectListByWhere(String where) {
PipelineEquipmentMpoint mpoint = new PipelineEquipmentMpoint();
mpoint.setWhere(where);
return pipelineEquipmentMpointDao.selectListByWhere(mpoint);
}
}

View File

@ -0,0 +1,126 @@
package com.sipai.service.data.impl;
import com.sipai.dao.data.PipelineEquipmentDao;
import com.sipai.dao.scada.MPointDao;
import com.sipai.entity.data.PipelineEquipment;
import com.sipai.entity.enums.DeviceTypeEnum;
import com.sipai.service.data.PipelineEquipmentService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class PipelineEquipmentServiceImpl implements PipelineEquipmentService {
@Autowired
private PipelineEquipmentDao pipelineEquipmentDao;
public PipelineEquipmentServiceImpl(PipelineEquipmentDao equipmentDao) {
this.pipelineEquipmentDao = equipmentDao;
}
@Override
public int insert(PipelineEquipment equipment) {
int result = pipelineEquipmentDao.insert(equipment);
if (result > 0) {
// 插入成功获取自增的ID
int generatedId = equipment.getId();
}
return result;
}
@Override
public boolean delete(Integer id) {
return pipelineEquipmentDao.deleteByPrimaryKey(id);
}
/*@Override
public boolean deleteBatch(List<Integer> idList) {
// 参数校验
if (CollectionUtils.isEmpty(idList)) {
return false;
}
// 执行批量删除
int count = pipelineEquipmentDao.deleteBatchByIds(idList);
return count > 0;
}*/
@Override
public boolean update(PipelineEquipment equipment) {
return pipelineEquipmentDao.updateByPrimaryKeySelective(equipment);
}
@Override
public PipelineEquipment selectByPrimaryKey(Integer id) {
PipelineEquipment pipelineEquipment = pipelineEquipmentDao.selectByPrimaryKey(id);
if (pipelineEquipment != null) {
//查询对应的设备名称
String typeCode = pipelineEquipment.getEquipmentType();
DeviceTypeEnum deviceType = DeviceTypeEnum.getByTypeCode(typeCode);
if (deviceType != null) {
pipelineEquipment.setEquipmentTypeName(deviceType.getTypeName());
}
return pipelineEquipment;
} else {
return null;
}
}
@Override
public List<PipelineEquipment> selectListByWhere(String where) {
PipelineEquipment pipelineEquipment = new PipelineEquipment();
pipelineEquipment.setWhere(where);
List<PipelineEquipment> list = pipelineEquipmentDao.selectListByWhere(pipelineEquipment);
for (PipelineEquipment equipment : list) {
String typeCode = equipment.getEquipmentType();
DeviceTypeEnum deviceType = DeviceTypeEnum.getByTypeCode(typeCode);
if (deviceType != null) {
equipment.setEquipmentTypeName(deviceType.getTypeName());
}
}
return list;
}
/*@Override
public List<PipelineEquipment> getEquipmentByStation(String stationCode) {
return equipmentDao.selectByStationCode(stationCode);
}
@Override
public List<PipelineEquipment> getEquipmentByType(String equipmentType) {
return equipmentDao.selectByEquipmentType(equipmentType);
}
@Override
public List<PipelineEquipment> getEquipmentByStatus(String status) {
return equipmentDao.selectByStatus(status);
}*/
/*@Override
public boolean updateEquipmentStatus(String id, String status) {
PipelineEquipment equipment = pipelineEquipmentDao.selectByPrimaryKey(id);
if (equipment == null) {
return false;
}
equipment.setStatus(status);
return pipelineEquipmentDao.updateByPrimaryKeySelective(equipment) > 0;
}
@Override
public boolean updateLastUploadTime(String id) {
PipelineEquipment equipment = pipelineEquipmentDao.selectByPrimaryKey(id);
if (equipment == null) {
return false;
}
equipment.setLastUploadTime(new Date());
return pipelineEquipmentDao.updateByPrimaryKeySelective(equipment) > 0;
}*/
}

View File

@ -0,0 +1,54 @@
package com.sipai.service.data.impl;
import com.sipai.dao.data.PipelineMpointLibraryDao;
import com.sipai.entity.data.PipelineMpointLibrary;
import com.sipai.service.data.PipelineMpointLibraryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class PipelineMpointLibraryServiceImpl implements PipelineMpointLibraryService {
@Autowired
private PipelineMpointLibraryDao pipelineMpointLibraryDao;
public PipelineMpointLibraryServiceImpl(PipelineMpointLibraryDao mpointLibraryDao) {
this.pipelineMpointLibraryDao = mpointLibraryDao;
}
@Override
public boolean insert(PipelineMpointLibrary mpointLibrary) {
return pipelineMpointLibraryDao.insert(mpointLibrary);
}
@Override
public boolean delete(String id) {
return pipelineMpointLibraryDao.deleteByPrimaryKey(id);
}
@Override
public int deleteBatch(List<String> idList) {
return pipelineMpointLibraryDao.deleteBatchByIds(idList);
}
@Override
public boolean update(PipelineMpointLibrary mpointLibrary) {
return pipelineMpointLibraryDao.updateByPrimaryKeySelective(mpointLibrary);
}
@Override
public PipelineMpointLibrary selectByPrimaryKey(String id) {
return pipelineMpointLibraryDao.selectByPrimaryKey(id);
}
@Override
public List<PipelineMpointLibrary> selectListByWhere(String where) {
PipelineMpointLibrary pipelineMpointLibrary = new PipelineMpointLibrary();
pipelineMpointLibrary.setWhere(where);
return pipelineMpointLibraryDao.selectListByWhere(pipelineMpointLibrary);
}
}

View File

@ -0,0 +1,24 @@
package com.sipai.service.kafka;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;
/**
* 消费者服务
*/
/*@Service
public class KafkaConsumerService {
@KafkaListener(topics = "topic_data", groupId = "my-group-2.2.0")
public void listen(String message, Acknowledgment ack) {
try {
// System.out.println("topic_data收到数据: " + message);
// 手动提交offset
ack.acknowledge();
} catch (Exception e) {
// 处理异常
System.err.println("Error processing message: " + e.getMessage());
}
}
}*/

View File

@ -0,0 +1,38 @@
package com.sipai.service.kafka;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.stereotype.Service;
/**
* 生产者服务
*/
/*@Service
public class KafkaProducerService {
private final KafkaTemplate<String, String> kafkaTemplate;
public KafkaProducerService(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void sendMessage(String topic, String message) {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topic, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onSuccess(SendResult<String, String> result) {
System.out.println("Sent message=[" + message +
"] with offset=[" + result.getRecordMetadata().offset() + "]");
}
@Override
public void onFailure(Throwable ex) {
System.err.println("Unable to send message=[" +
message + "] due to : " + ex.getMessage());
}
});
}
}*/

View File

@ -0,0 +1,62 @@
package com.sipai.service.mqtt;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.mqtt.MqttConfig;
import com.sipai.entity.scada.MPoint;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/16:44
* @Description:
*/
public interface MqttConfigService {
public abstract MqttConfig selectByPrimaryKey(String id);
public abstract Integer deleteByPrimaryKey(String id);
public abstract Integer insert(MqttConfig entity);
public abstract Integer updateByPrimaryKeySelective(MqttConfig entity);
public abstract List<MqttConfig> selectListByWhere(String wherestr);
public abstract Integer deleteByWhere(String wherestr);
public String connect(String id);
/**
* 根据主题返回emqx代理地址 websocket方式
* sj 2021-09-15
* @param topic
* @return
*/
public JSONObject getEmqxHost4WS(String topic);
/**
* 根据主题返回emqx代理地址 tcp方式
* sj 2021-09-15
* @param topic
* @return
*/
public String getEmqxHost4TCP(String topic);
public void doSendMqttVue(List<MPoint> list, String topic);
/**
* @param jsonArray 需要推送的数据
* @param topic 推送的主题
*/
public void doSendView(JSONArray jsonArray, String topic);
/**
* @param jsonObject 需要推送的数据
* @param topic 推送的主题
*/
public void doSendJson(JSONObject jsonObject, String topic);
}

View File

@ -0,0 +1,28 @@
package com.sipai.service.mqtt;
import com.sipai.entity.mqtt.MqttConfigTopic;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/17:56
* @Description:
*/
public interface MqttConfigTopicService {
public abstract MqttConfigTopic selectByPrimaryKey(String id);
public abstract Integer deleteByPrimaryKey(String id);
public abstract Integer insert(MqttConfigTopic entity);
public abstract Integer updateByPrimaryKeySelective(MqttConfigTopic entity);
public abstract List<MqttConfigTopic> selectListByWhere(String wherestr);
public abstract Integer deleteByWhere(String wherestr);
public abstract List<MqttConfigTopic> selectListByPid(String pid);
}

View File

@ -0,0 +1,57 @@
package com.sipai.service.mqtt;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.scheduling.annotation.Scheduled;
public interface MqttService {
/**
* 用于提供云平台 给plc发布指令接口
* @param json
* @param topic
* @param userId
* @param bizId
* @return
*/
public abstract int doPublish(JSONObject json, String topic, String userId, String bizId);
/**
* 处理mqtt订阅到的数据
* @param bizId
* @param topic
* @param ip4
* @param port
* @param jsonArray
*/
public abstract void doHandle(String bizId, String topic, String ip4, String port, JSONArray jsonArray);
/**
* 处理mqtt订阅到的数据 -- (补发的数据 1.不报警 2.不更新主表 3.AI点3分钟存一次 DI点每次都存
* @param bizId
* @param topic
* @param ip4
* @param port
* @param jsonArray
*/
public abstract void doHandleHis(String bizId, String topic, String ip4, String port, JSONArray jsonArray);
/**
* 网关数据全部召回
* @param bizId
* @return
*/
public abstract void doRecall(String bizId,JSONObject jsonObject);
/**
* 发送 rabbitmq
*
* @return
*/
public abstract void sentRabbitmq(String exchange, String key, String value_BigDecimal, String date);
/**
* 清理测量点对象缓存
*/
@Scheduled(fixedRate = 3600000) // 每小时清理一次
void cleanCache();
}

View File

@ -0,0 +1,229 @@
package com.sipai.service.mqtt;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.user.Company;
import com.sipai.service.rabbitmq.MQService;
import com.sipai.service.user.CompanyService;
import com.sipai.tools.CommUtil;
import com.sipai.tools.SpringContextUtil;
import org.eclipse.paho.client.mqttv3.*;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* 发布消息的回调类
* <p>
* 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
* 每个客户机标识都需要一个回调实例。在此示例中,构造函数传递客户机标识以另存为实例数据。
* 在回调中,将它用来标识已经启动了该回调的哪个实例。
* 必须在回调类中实现三个方法:
* <p>
* public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
* <p>
* public void connectionLost(Throwable cause)在断开连接时调用。
* <p>
* public void deliveryComplete(MqttDeliveryToken token))
* 接收到已经发布的 QoS 1 或 QoS 2 消息的传递令牌时调用。
* 由 MqttClient.connect 激活此回调。
*/
public class PushCallback implements MqttCallbackExtended {
InetAddress ip4;//ip
{
try {
ip4 = Inet4Address.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames;
String port = "";//端口
{
try {
objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
// port = objectNames.iterator().next().getKeyProperty("port");
port = "8080";
} catch (MalformedObjectNameException e) {
e.printStackTrace();
}
}
private MqttClient client;
private MqttConnectOptions options;
private String[] topic;
private int[] qos;
public PushCallback(MqttClient client, MqttConnectOptions options, String[] topic, int[] qos) {
this.client = client;
this.options = options;
this.topic = topic;
this.qos = qos;
}
/**
* 连接断开回调方法
*/
public void connectionLost(Throwable cause) {
System.out.println("===连接断开回调方法");
try {
if (null != client && !client.isConnected()) {
System.out.println("尝试重新连接");
client.connect(options);
} else {
System.out.println("尝试建立新连接");
client.connect(options);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接成功回调方法
*/
@Override
public void connectComplete(boolean reconnect, String serverURI) {
System.out.println("===连接成功回调方法");
try {
if (null != topic && null != qos) {
if (client.isConnected()) {
client.subscribe(topic, qos);
System.out.println("mqtt连接成功");
} else {
System.out.println("mqtt连接失败");
}
}
} catch (Exception e) {
System.out.println("mqtt订阅主题异常:" + e);
}
}
public void deliveryComplete(IMqttDeliveryToken token) {
// System.out.println("deliveryComplete---------" + token.isComplete());
}
public void messageArrived(String topic, MqttMessage message) {
try {
JSONArray jsonArray = JSONArray.parseArray(message.toString());
// System.out.println(topic + "===开始===" + CommUtil.nowDate() + "===" + jsonArray.size());
String unitId = topic.substring(0, 4);//截取topic的前面部分作为厂id
MqttService mqttService = (MqttService) SpringContextUtil.getBean("mqttService");
//正常的主题 -- 数据处理
mqttService.doHandle(unitId, topic, ip4.toString(), port, jsonArray);
} catch (Exception e) {
System.out.println(topic + "执行失败" + e);
}
}
/**
* 日期格式字符串转换成时间戳
*
* @param date_str 字符串日期
* @param format 如yyyy-MM-dd HH:mm:ss
* @return
*/
public static String date2TimeStamp(String date_str, String format) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return String.valueOf(sdf.parse(date_str).getTime() / 1000);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 发送 rabbitmq
*
* @param key
* @param value_BigDecimal
* @param date
*/
public static void sentRabbitmq(String exchange, String key, String value_BigDecimal, String date) {
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("id", key);
jsonObject1.put("value", value_BigDecimal);
jsonObject1.put("time", date);
MQService mqService = (MQService) SpringContextUtil.getBean("mQService");
mqService.sendMQ(exchange, jsonObject1.toString());
}
public static void sentRabbitMqMpoint(String exchange, String json) {
MQService mqService = (MQService) SpringContextUtil.getBean("mQService");
mqService.sendMQ(exchange, json);
}
public String doPost(String URL) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
HttpURLConnection conn = null;
try {
java.net.URL url = new URL(URL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
//发送POST请求必须设置为true
conn.setDoOutput(true);
conn.setDoInput(true);
//设置连接超时时间和读取超时时间
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
//获取输出流
out = new OutputStreamWriter(conn.getOutputStream());
String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
out.write(jsonStr);
out.flush();
out.close();
//取得输入流并使用Reader读取
if (200 == conn.getResponseCode()) {
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} else {
System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return result.toString();
}
}

View File

@ -0,0 +1,348 @@
package com.sipai.service.mqtt.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.mqtt.Mqtt;
import com.sipai.entity.mqtt.MqttProperties;
import com.sipai.entity.scada.MPoint;
import com.sipai.service.mqtt.PushCallback;
import com.sipai.dao.mqtt.MqttConfigDao;
import com.sipai.entity.mqtt.MqttConfig;
import com.sipai.entity.mqtt.MqttConfigTopic;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.service.mqtt.MqttConfigTopicService;
import com.sipai.tools.CommUtil;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/16:45
* @Description:
*/
@Service
public class MqttConfigServiceImpl implements MqttConfigService {
private final MqttProperties mqttProperties;
@Autowired
private MqttConfigDao mqttConfigDao;
@Autowired
private MqttConfigTopicService mqttConfigTopicService;
private static MqttClient mqttClient1;
// 构造器注入
@Autowired
public MqttConfigServiceImpl(MqttProperties mqttProperties) {
this.mqttProperties = mqttProperties;
}
private static MqttClient connect(String brokeraddress, String clientId, String userName, String password) throws MqttException {
MemoryPersistence persistence = new MemoryPersistence();
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(userName);
connOpts.setPassword(password.toCharArray());
connOpts.setConnectionTimeout(1000);
connOpts.setKeepAliveInterval(1000);
mqttClient1 = new MqttClient(brokeraddress, clientId, persistence);
mqttClient1.connect(connOpts);
return mqttClient1;
}
@Override
public MqttConfig selectByPrimaryKey(String id) {
return mqttConfigDao.selectByPrimaryKey(id);
}
@Override
public Integer deleteByPrimaryKey(String id) {
return mqttConfigDao.deleteByPrimaryKey(id);
}
@Override
public Integer insert(MqttConfig entity) {
return mqttConfigDao.insert(entity);
}
@Override
public Integer updateByPrimaryKeySelective(MqttConfig entity) {
return mqttConfigDao.insert(entity);
}
@Override
public List<MqttConfig> selectListByWhere(String whereStr) {
MqttConfig entity = new MqttConfig();
entity.setWhere(whereStr);
return mqttConfigDao.selectListByWhere(entity);
}
@Override
public Integer deleteByWhere(String whereStr) {
return mqttConfigDao.deleteByWhere(whereStr);
}
@Override
public String connect(String id) {
String clientId = "";
MqttConfig mqttConfig = mqttConfigDao.selectByPrimaryKey(id);
if (mqttConfig != null) {
clientId = mqttConfig.getTomcatPort() + "-" + CommUtil.getUUID();
System.out.println(clientId);
String sql = "where id = '" + mqttConfig.getId() + "'";
mqttConfig.setWhere(sql);
List<MqttConfig> list_config = mqttConfigDao.selectListByWhere(mqttConfig);
List<String> topic_str = new ArrayList<>();
//每个客户端根据配置的tomcat端口号进行分区连接
if (list_config != null && list_config.size() > 0) {
//循环配置主表
for (int i = 0; i < list_config.size(); i++) {
String sql_detail = "where pid = '" + list_config.get(i).getId() + "'";
List<MqttConfigTopic> list_topic = mqttConfigTopicService.selectListByWhere(sql_detail);
if (list_topic != null && list_topic.size() > 0) {
//循环配置附表获取所有topic
for (int j = 0; j < list_topic.size(); j++) {
//配置的_UP主题
// topic_str.add("$queue/" + list_topic.get(j).getTopic());
topic_str.add(list_topic.get(j).getTopic());
}
}
}
}
//配置的条数即为数组的长度
String[] topic = new String[topic_str.size()];
System.out.println("订阅主题:" + topic_str);
int[] qos = new int[topic_str.size()];
for (int j = 0; j < topic_str.size(); j++) {
topic[j] = topic_str.get(j);
qos[j] = 0;
}
try {
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setConnectionTimeout(1000);
//每隔1.5*10秒的时间向客户端发送个消息判断客户端是否在线
connOpts.setKeepAliveInterval(1000);
//自动重连
connOpts.setAutomaticReconnect(true);
connOpts.setUserName(mqttProperties.getUsername());
connOpts.setPassword(mqttProperties.getPassword().toCharArray());
if (mqttClient1 != null) {
System.out.println("已连接");
//回调
mqttClient1.setCallback(new PushCallback(mqttClient1, connOpts, topic, qos));
//订阅
mqttClient1.subscribe(topic, qos);
} else {
System.out.println("重新连接");
//连接
mqttClient1 = connect(mqttConfig.getBrokerIp(), clientId, mqttProperties.getUsername(), mqttProperties.getPassword());
//回调
mqttClient1.setCallback(new PushCallback(mqttClient1, connOpts, topic, qos));
//订阅
mqttClient1.subscribe(topic, qos);
}
} catch (MqttException me) {
me.printStackTrace();
}
}
return clientId;
}
public Boolean clientStatus(String clientId) {
boolean status = true;
try {
System.out.println(mqttProperties.getDashboard01() + "/api/v4/clients/" + clientId);
URL url = new URL(mqttProperties.getDashboard01() + "/api/v4/clients/" + clientId);
Base64 b = new Base64();
String encoding = b.encodeAsString(new String("admin:sipai@64368180").getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = connection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(content));
JSONObject jsonObject = JSONObject.parseObject(in.readLine());
String data = jsonObject.get("data").toString();
JSONArray jsonArrayStr = JSONArray.parseArray(data);
if (jsonArrayStr.size() > 0) {
JSONObject jsonObject1 = jsonArrayStr.getJSONObject(0);
if (jsonObject1.get("connected").equals(true)) {
status = true;
} else {
status = false;
}
} else {
status = false;
}
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
@Override
public JSONObject getEmqxHost4WS(String topic) {
JSONObject jsonObject = new JSONObject();
List<MqttConfigTopic> list = mqttConfigTopicService.selectListByWhere("where topic = '" + topic + "'");
if (list != null && list.size() > 0) {
MqttConfig mqttConfig = new MqttConfig();
//增加个循环查出所有的 有些旧数据 跳过 只查有主表数据的
for (int i = 0; i < list.size(); i++) {
mqttConfig.setWhere("where id = '" + list.get(i).getPid() + "'");
List<MqttConfig> list2 = mqttConfigDao.selectListByWhere(mqttConfig);
if (list2 != null && list2.size() > 0) {
if (list2.get(0).getBrokerIp() != null && !list2.get(0).getBrokerIp().trim().equals("")) {
String ip = list2.get(0).getBrokerIp();
ip = ip.replace("tcp://", "");
String host = ip.substring(0, ip.indexOf(":"));
//一期
if (host != null && host.equals("172.16.242.16")) {
jsonObject.put("host", "58.254.140.62");
jsonObject.put("port", "8088");
}
//二期
if (host != null && host.equals("172.16.242.24")) {
jsonObject.put("host", "58.254.140.121");
jsonObject.put("port", "8083");
}
}
break;
}
}
}
return jsonObject;
}
@Override
public String getEmqxHost4TCP(String topic) {
String host = mqttProperties.getBrokerAddress();//默认一期
List<MqttConfigTopic> list = mqttConfigTopicService.selectListByWhere("where topic = '" + topic + "'");
if (list != null && list.size() > 0) {
MqttConfig mqttConfig = new MqttConfig();
//增加个循环查出所有的 有些旧数据 跳过 只查有主表数据的
for (int i = 0; i < list.size(); i++) {
mqttConfig.setWhere("where id = '" + list.get(i).getPid() + "'");
List<MqttConfig> list2 = mqttConfigDao.selectListByWhere(mqttConfig);
if (list2 != null && list2.size() > 0) {
if (list2.get(0).getBrokerIp() != null && !list2.get(0).getBrokerIp().trim().equals("")) {
host = list2.get(0).getBrokerIp();
}
break;
}
}
}
return host;
}
@Async
public void doSendMqttVue(List<MPoint> list, String topic) {
JSONArray jsonVue = (JSONArray) JSONArray.toJSON(list);
MqttMessage message = new MqttMessage(jsonVue.toString().getBytes());
message.setQos(0);
message.setRetained(false);
try {
String host = this.getEmqxHost4TCP(topic);
if (host != null && !host.equals("")) {
String[] str = host.split(";");
String ip = str[0];//连接的ip
String topic_vue = topic;
if (topic != null && topic.contains("_IM")) {
topic_vue = topic.replace("_IM", "");
}
// topic_vue = topic_vue + "_VIEW";
topic_vue = topic_vue.substring(0, 4) + "_01_UP_VIEW";
int size = list != null ? list.size() : 0;
StringBuilder ids = new StringBuilder();
if (list != null) {
int max = Math.min(5, list.size());
for (int i = 0; i < max; i++) {
ids.append(list.get(i).getId());
if (i < max - 1) ids.append(",");
}
}
System.out.println("推送VIEW: topic=" + topic_vue + " size=" + size);
if (mqttClient1 != null && mqttClient1.isConnected()) {
//发布
// System.out.println("推送前端:" + topic_vue);
mqttClient1.publish(topic_vue, message);
} else {
System.out.println("===重新连接===" + "推VUE===主题:" + topic_vue + "===" + ip + "===" + CommUtil.nowDate() + "===");
//连接
String clientId = "send_vue_" + str[2];
mqttClient1 = connect(ip, clientId, mqttProperties.getUsername(), mqttProperties.getPassword());
//发布
mqttClient1.publish(topic_vue, message);
}
}
} catch (MqttException e) {
e.printStackTrace();
}
}
@Async
public void doSendView(JSONArray jsonArray, String topic) {
MqttMessage message = new MqttMessage(jsonArray.toString().getBytes());
message.setQos(0);
message.setRetained(false);
try {
if (mqttClient1 != null && mqttClient1.isConnected()) {
//发布
mqttClient1.publish(topic, message);
} else {
mqttClient1 = connect(mqttProperties.getBrokerAddress(), "send_vue_" + CommUtil.getUUID(), mqttProperties.getUsername(), mqttProperties.getPassword());
//发布
mqttClient1.publish(topic, message);
}
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* @param jsonObject 需要推送的数据
* @param topic 推送的主题
*/
@Async
public void doSendJson(JSONObject jsonObject, String topic) {
MqttMessage message = new MqttMessage(jsonObject.toString().getBytes());
message.setQos(0);
message.setRetained(false);
try {
if (mqttClient1 != null && mqttClient1.isConnected()) {
//发布
mqttClient1.publish(topic, message);
} else {
mqttClient1 = connect(mqttProperties.getBrokerAddress(), "send_vue_" + CommUtil.getUUID(), mqttProperties.getUsername(), mqttProperties.getPassword());
//发布
mqttClient1.publish(topic, message);
}
} catch (MqttException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,61 @@
package com.sipai.service.mqtt.impl;
import com.sipai.dao.mqtt.MqttConfigTopicDao;
import com.sipai.entity.mqtt.MqttConfigTopic;
import com.sipai.service.mqtt.MqttConfigTopicService;
import com.sipai.tools.DataSourceEnum;
import com.sipai.tools.DataSourceTypeAnno;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @Auther: sj
* @Date: 2021/03/24/17:56
* @Description:
*/
@Service
public class MqttConfigTopicServiceImpl implements MqttConfigTopicService {
@Autowired
private MqttConfigTopicDao mqttConfigTopicDao;
@Override
public MqttConfigTopic selectByPrimaryKey(String id) {
return mqttConfigTopicDao.selectByPrimaryKey(id);
}
@Override
public Integer deleteByPrimaryKey(String id) {
return mqttConfigTopicDao.deleteByPrimaryKey(id);
}
@Override
public Integer insert(MqttConfigTopic entity) {
return mqttConfigTopicDao.insert(entity);
}
@Override
public Integer updateByPrimaryKeySelective(MqttConfigTopic entity) {
return mqttConfigTopicDao.updateByPrimaryKeySelective(entity);
}
@Override
public List<MqttConfigTopic> selectListByWhere(String wherestr) {
MqttConfigTopic entity = new MqttConfigTopic();
entity.setWhere(wherestr);
return mqttConfigTopicDao.selectListByWhere(entity);
}
@Override
public Integer deleteByWhere(String wherestr) {
return mqttConfigTopicDao.deleteByWhere(wherestr);
}
@Override
public List<MqttConfigTopic> selectListByPid(String pid) {
return mqttConfigTopicDao.selectListByPid(pid);
}
}

View File

@ -0,0 +1,553 @@
package com.sipai.service.mqtt.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sipai.entity.mqtt.Mqtt;
import com.sipai.entity.mqtt.MqttProperties;
import com.sipai.entity.scada.MPoint;
import com.sipai.entity.scada.MPointES;
import com.sipai.entity.scada.MPointHistory;
import com.sipai.service.Listener.ListenerPointService;
import com.sipai.service.mqtt.MqttConfigService;
import com.sipai.service.mqtt.MqttConfigTopicService;
import com.sipai.service.mqtt.MqttService;
import com.sipai.service.rabbitmq.MQService;
import com.sipai.service.scada.MPointHistoryService;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.*;
import jodd.util.ClassUtil;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.redisson.api.RBatch;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Service("mqttService")
public class MqttServiceImpl implements MqttService {
private final MqttProperties mqttProperties;
@Autowired
private MPointService mPointService;
@Autowired
private MqttConfigService mqttConfigService;
@Autowired
private MqttConfigTopicService mqttConfigTopicService;
@Autowired
private ListenerPointService listenerPointService;
@Autowired
private RedissonClient redissonClient;
private static MqttClient mqttClient;
private static String ipStr = "";
private static final Logger loggger = LoggerFactory.getLogger(ClassUtil.class);
//测量点对象缓存
private final Map<String, MPoint> mPointCache = new ConcurrentHashMap<>();
private final Set<String> notFoundKeys = ConcurrentHashMap.newKeySet();
@Override
@Scheduled(fixedRate = 3600000)//每小时清理一次
public void cleanCache() {
loggger.info("清理缓存(" + mPointCache.size() + " 条):" + CommUtil.nowDate());
mPointCache.clear();
notFoundKeys.clear();
}
public MqttServiceImpl(MqttProperties mqttProperties) {
this.mqttProperties = mqttProperties;
}
private static MqttClient connect(String brokeraddress, String clientId, String userName, String password) throws MqttException {
ipStr = brokeraddress;
MemoryPersistence persistence = new MemoryPersistence();
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(userName);
connOpts.setPassword(password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
// String[] uris = {"tcp://10.100.124.206:1883","tcp://10.100.124.207:1883"};
// connOpts.setServerURIs(uris); //起到负载均衡和高可用的作用
// MqttClient mqttClient = new MqttClient(brokeraddress, clientId, persistence);
mqttClient = new MqttClient(brokeraddress, clientId, persistence);
//mqttClient.setCallback(new PushCallback("test"));
mqttClient.connect(connOpts);
return mqttClient;
}
@Async("getAsyncMqttHandle")
@Override
public void doHandle(String bizId, String topic, String ip4, String port, JSONArray jsonArray) {
// System.out.println("MQTT接收: biz=" + bizId + " topic=" + topic + " msgCount=" + jsonArray.size());
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
// 解析时间戳
String timestamp = jsonObject.getString("timestamp");
String[] times = timestamp.split("\\.");
String date = CommUtil.timeStamp2Date(times[0], "yyyy-MM-dd HH:mm:ss");
// 解析数据对象
JSONObject data = jsonObject.getJSONObject("Data");
if (data == null || data.isEmpty()) {
loggger.warn("Data为空跳过: @{}", date);
continue;
}
List<MPointES> redisList = new ArrayList<>();
List<MPoint> vueList = new ArrayList<>();
// 遍历数据条目
for (String key : data.keySet()) {
String valueStr = data.getString(key);
// 过滤无效值
if (!isValidValue(valueStr)) {
loggger.warn("值无效,跳过: key={} raw={} @{}", key, valueStr, date);
continue;
}
// 获取点位信息
MPoint mPoint = getMPointCacheOrES(bizId, key);
if (mPoint == null) {
boolean inNotFound = notFoundKeys.contains(key);
loggger.warn("点位不存在,跳过: key={} notFoundCache={} @{}", key, inNotFound, date);
continue;
}
// 处理数值转换、倍率计算、取反操作、推报警信息、发送Kafka消息
BigDecimal value = handleValueConversion(bizId, valueStr, key, date, vueList);
if (value == null) {
loggger.warn("数值转换失败,跳过: key={} raw={} @{}", key, valueStr, date);
continue;
}
// 处理ES数据
MPointES esPoint = buildEsPoint(mPoint, value, date);
redisList.add(esPoint);
}
// 推送前端数据
// loggger.info("准备推送前端: topic={} size={} @{}", topic, vueList.size(), date);
mqttConfigService.doSendMqttVue(vueList, topic);
// 批量写入Redis
saveToRedisBatch(redisList);
// loggger.info("批量写入Redis完成: size={} @{}", redisList.size(), date);
}
}
/**
* 校验值是否有效(非空且长度合法)
*/
private boolean isValidValue(String value) {
if (value == null || value.isEmpty()) {
loggger.warn("无效值: 空字符串");
return false;
}
BigDecimal bd = new BigDecimal(value);
String plainValue = bd.toPlainString();
String[] parts = plainValue.split("\\.");
boolean ok = parts[0].length() <= 15;
if (!ok) {
loggger.warn("无效值: 整数位过长 len={} raw={}", parts[0].length(), value);
}
return ok;
}
/**
* 处理数值转换、倍率计算、取反操作、推报警信息、发送Kafka消息
*/
private BigDecimal handleValueConversion(String unitId, String valueStr, String key, String date, List<MPoint> vueList) {
try {
double valDou = Double.parseDouble(valueStr);
MPoint mPoint = getMPointCacheOrES(unitId, key);
if (mPoint == null) {
return null;
}
// 倍率计算
BigDecimal rate = mPoint.getRate() != null ? mPoint.getRate() : BigDecimal.ONE;
BigDecimal value = (valDou == 0 || rate.compareTo(BigDecimal.ZERO) == 0)
? BigDecimal.ZERO
: rate.multiply(new BigDecimal(valueStr)).divide(BigDecimal.ONE, 10, RoundingMode.HALF_UP);
// 取反操作
if ("1".equals(mPoint.getDirecttype())) {
value = "0".equals(valueStr) ? BigDecimal.ONE : ("1".equals(valueStr) ? BigDecimal.ZERO : value);
}
// 推送报警信息
if (mPoint.getTriggeralarm() != null && !"0".equals(mPoint.getTriggeralarm().trim())) {
// loggger.info("推送报警: {}={} @{}", key, value, date);
// mPointService.sendKafka4MQTT_Alarm(key, value, date, 0, 1);
}
// 发送Kafka消息
// mPointService.sendKafka4MQTT(unitId,key, value, date, 0, 1, mPoint.getSignaltype());
// 构建前端数据
buildVuePoint(mPoint, value, date, vueList);
return value;
} catch (NumberFormatException e) {
loggger.error("数值转换失败: {}", valueStr, e);
return null;
}
}
/**
* 构建前端展示用点位对象
*/
private void buildVuePoint(MPoint mPoint, BigDecimal value, String date, List<MPoint> vueList) {
MPoint vuePoint = new MPoint();
vuePoint.setId(mPoint.getId());
vuePoint.setMeasuredt(date);
int numtail = doNumtail(mPoint.getNumtail());
vuePoint.setParmvalue(value.setScale(numtail, RoundingMode.HALF_UP));
vueList.add(vuePoint);
}
/**
* 构建ES存储用点位对象
*/
private MPointES buildEsPoint(MPoint mPoint, BigDecimal value, String date) {
MPoint esPoint = new MPoint();
esPoint.setId(mPoint.getId());
esPoint.setMeasuredt(date);
esPoint.setParmvalue(value);
esPoint.setNumtail(mPoint.getNumtail());
return MPointES.format(esPoint);
}
/**
* 批量保存数据到Redis
*/
private void saveToRedisBatch(List<MPointES> esList) {
if (esList.isEmpty()) {
return;
}
int batchSize = 200;
int total = esList.size();
int batches = (total + batchSize - 1) / batchSize;
try {
for (int i = 0; i < batches; i++) {
int start = i * batchSize;
int end = Math.min((i + 1) * batchSize, total);
RBatch batch = redissonClient.createBatch();
for (MPoint mPoint : esList.subList(start, end)) {
int num = mPoint.getId().hashCode() % 25;
String dt = mPoint.getMeasuredt().replace("T", " ").replace("Z", "");
int numtail = doNumtail(mPoint.getNumtail());
String val = mPoint.getParmvalue().setScale(numtail, RoundingMode.HALF_UP)
+ ";" + mPoint.getParmvalue() + ";" + dt;
batch.getMapCache(CommString.RedisMpointFlag + num)
.fastPutAsync(mPoint.getId(), val, 1, TimeUnit.DAYS);
}
batch.execute();
}
} catch (Exception e) {
loggger.error("Redis批量保存失败", e);
}
}
@Async("getAsyncMqttHandle")
@Override
public void doHandleHis(String bizId, String topic, String ip4, String port, JSONArray jsonArray) {
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String timestamp = jsonObject.get("timestamp").toString();//时间戳
String[] times = timestamp.split("\\.");
String date = CommUtil.timeStamp2Date(times[0], "yyyy-MM-dd HH:mm:ss");
//数据
JSONObject data = jsonObject.getJSONObject("Data");
MPointService mPointService = (MPointService) SpringContextUtil.getBean("mPointService");
MPointHistoryService mPointHistoryService = (MPointHistoryService) SpringContextUtil.getBean("mPointHistoryService");
MPointHistory mPointHistory = new MPointHistory();
for (String str : data.keySet()) {
String key = str;//测量点id
String value = data.get(str) + "";
//过滤掉长度超过15位的数值 money无法存
if (value != null && !value.equals("")) {
BigDecimal bd = new BigDecimal(value);
value = bd.toPlainString();
if (value.contains(".")) {
String[] vals = value.split("\\.");
if (vals[0].length() > 15) {
//超出
continue;
} else {
//未超出
}
} else {
if (value.length() > 15) {
//超出
continue;
} else {
//未超出
}
}
} else {
//为空 过滤掉 不存日志
continue;
}
BigDecimal value_BigDecimal = null;
double valDou = 0;//判断是否为0 或者0.00 或 0.000等
//将json中为""的过滤掉
if (value != null && !value.equals("")) {
valDou = Double.parseDouble(value);//判断是否为0 或者0.00 或 0.000等
// MPoint mPoint = mPointService.selectById(bizId, key);
MPoint mPoint = mPointService.selectById(bizId, key.toString());
if (mPoint != null) {
BigDecimal numDecimal = mPoint.getRate();
if (valDou == 0 || mPoint.getRate().equals(0)) {
value_BigDecimal = new BigDecimal(0);
} else {
value_BigDecimal = numDecimal.multiply(new BigDecimal(value));
//截取长度防止 过长 除1再截取10位
value_BigDecimal = value_BigDecimal.divide(new BigDecimal(1), 10, BigDecimal.ROUND_HALF_UP);
}
//取反操作
if (mPoint.getDirecttype() != null && mPoint.getDirecttype().equals("1")) {
//取反
if (value.equals("0")) {
value_BigDecimal = new BigDecimal(1);
} else if (value.equals("1")) {
value_BigDecimal = new BigDecimal(0);
} else {
//正常
}
} else {
//正常
}
try {
//DI点直接存
if (mPoint.getSignaltype() != null && mPoint.getSignaltype().equals("DI")) {
mPointHistory.setMeasuredt(date);
mPointHistory.setParmvalue(value_BigDecimal);
mPointHistory.setTbName("[tb_mp_" + key + "]");
mPointHistory.setUserid(ip4 + ":" + port);
mPointHistoryService.save(bizId, mPointHistory);
}
//AI点3分钟存一次
if (mPoint.getSignaltype() != null && mPoint.getSignaltype().equals("DI")) {
String sqlStr = "where MeasureDT>dateadd(mi,-3,'" + date + "') order by MeasureDT desc";
/*List<MPointHistory> mPointHistoryList = mPointHistoryService.selectTopNumListByTableAWhere(mPoint.getBizid(),"[tb_mp_" + key + "]", sqlStr, "1");
if (mPointHistoryList != null && mPointHistoryList.size() > 0) {
//3分钟内存在 则不存
} else {
mPointHistory.setMeasuredt(date);
mPointHistory.setParmvalue(value_BigDecimal);
mPointHistory.setTbName("[tb_mp_" + key + "]");
mPointHistory.setUserid(ip4 + ":" + port);
mPointHistoryService.save(bizId, mPointHistory);
}*/
}
} catch (Exception e) {
System.out.println("新增子表--执行结果:" + e);
}
}
}
}
}
}
/**
* 发送 rabbitmq
*
* @param key
* @param value_BigDecimal
* @param date
*/
@Override
public void sentRabbitmq(String exchange, String key, String value_BigDecimal, String date) {
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("id", key);
jsonObject1.put("value", value_BigDecimal);
jsonObject1.put("time", date);
MQService mqService = (MQService) SpringContextUtil.getBean("mQService");
mqService.sendMQ(exchange, jsonObject1.toString());
}
/**
* 指令下发
*
* @param json
* @param topic
* @param userId
* @param bizId
* @return
*/
@Override
public int doPublish(JSONObject json, String topic, String userId, String bizId) {
try {
MqttMessage message = new MqttMessage(json.toString().getBytes());
message.setQos(2);
message.setRetained(false);
//查询主题属于哪个代理
String topic_up = "";
if (topic != null && !topic.equals("")) {
topic_up = topic.replace("_DOWN", "_UP");
}
String host = mqttConfigService.getEmqxHost4TCP(topic_up);
System.out.println("指令下发:" + host);
//连接
mqttClient = connect(host, "gy_publish_8080", mqttProperties.getUsername(), mqttProperties.getPassword());
//发布
mqttClient.publish(topic, message);
//断开连接
mqttClient.disconnect();
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
return 0;
}
/**
* 召回网关全部数据
*
* @param bizId
* @param jsonObject
*/
@Override
public void doRecall(String bizId, JSONObject jsonObject) {
try {
MqttMessage message = new MqttMessage(jsonObject.toString().getBytes());
message.setQos(2);
message.setRetained(false);
//查询主题属于哪个代理
String topic_up = bizId + "_01_UP";
String host = mqttConfigService.getEmqxHost4TCP(topic_up);
System.out.println(CommUtil.nowDate() + "数据召回-执行Recall" + bizId + "_01_RECALL" + "------" + host);
//连接
mqttClient = connect(host, "gy_recall_8080", mqttProperties.getUsername(), mqttProperties.getPassword());
//发布主题
mqttClient.publish(bizId + "_01_RECALL", message);
//断开连接
mqttClient.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 将处理后的mqtt消息传到vue前端
*/
@Async
public void doSendMqttVue(List<MPoint> list, String topic) {
JSONArray jsonVue = (JSONArray) JSONArray.toJSON(list);
MqttMessage message = new MqttMessage(jsonVue.toString().getBytes());
message.setQos(0);
message.setRetained(false);
try {
if (mqttClient == null) {
System.out.println("掉线_sendMqttVue");
mqttClient = connect(mqttProperties.getBrokerAddress(), "gy_sendMqttVue" + CommUtil.getUUID(), mqttProperties.getUsername(), mqttProperties.getPassword());
} else {
// System.out.println("正常_sendMqttVue");
}
String topic_vue = topic;
if (topic != null && topic.contains("_IM")) {
topic_vue = topic.replace("_IM", "");
}
topic_vue = topic_vue + "_VUE";
mqttClient.publish(topic_vue, message);
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 返回精度
*
* @param num
* @return
*/
public int doNumtail(String num) {
int numtail = 0;
if (num != null && !num.trim().equals("")) {
//0.00这种后面不用 暂时写死 以后标准全部用数字
if (num.contains(".")) {
if (num.equals("0.0")) {
numtail = 1;
}
if (num.equals("0.00")) {
numtail = 2;
}
if (num.equals("0.000")) {
numtail = 3;
}
if (num.equals("0.0000")) {
numtail = 4;
}
} else {
numtail = Integer.parseInt(num);
}
} else {
numtail = 0;
}
return numtail;
}
/**
* 优先从缓存查询MPoint对象不存在则去es中查询
*
* @param key
* @return
*/
private MPoint getMPointCacheOrES(String unitId, String key) {
// 查询缓存是否存在
if (mPointCache.containsKey(key)) {
MPoint mp = mPointCache.get(key);
// loggger.debug("缓存命中: key={} id={}", key, mp.getId());
return mp;
}
// 点位不存在 新加的点位需要定时清理缓存的时候才会进入缓存不然频繁去查询es
if (notFoundKeys.contains(key)) {
// loggger.debug("已标记未找到跳过ES查询: key={}", key);
return null;
}
// 从ES查询
MPoint mPoint = mPointService.selectById(unitId, key);
if (mPoint != null) {
//添加缓存
mPointCache.put(key, mPoint);
// loggger.debug("ES查询成功并缓存: key={} id={}", key, mPoint.getId());
} else {
//没有该点位
notFoundKeys.add(key);
// loggger.warn("ES未找到点位加入未找到集合: key={}", key);
}
return mPoint;
}
}

View File

@ -0,0 +1,134 @@
package com.sipai.service.opc;
import com.sipai.entity.scada.MPoint;
import com.sipai.service.opc.OpcUaService;
import com.sipai.service.scada.MPointService;
import com.sipai.tools.CommString;
import com.sipai.tools.CommUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.redisson.api.RBatch;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
/**
* 初始化订阅数据
*/
@Service
public class InitOpcUaService {
@Autowired(required = false)
private OpcUaService opcUaService;
@Autowired
private MPointService mPointService;
// 本地缓存
private final Cache<String, MPoint> mPointCache = Caffeine.newBuilder()
.maximumSize(10000) // 仅设置最大缓存数量
// .expireAfterWrite(1, TimeUnit.HOURS) // 1小时后过期
.build();
// 已订阅的点位集合
private Set<String> subscribedNodeIds = new HashSet<>();
@PostConstruct
public void init() {
if (opcUaService == null) {
System.out.println("OPC UA 未启动请检查yml配置文件钟opc: enabled: true");
return;
}
try {
//查询所有的opcua采集点位
List<String> nodeIdList = fetchNodeIdsFromEs();
for (String nodeId : nodeIdList) {
MPoint mPoint = mPointCache.get(nodeId, key -> mPointService.selectById("",nodeId));
System.out.println(mPoint);
Consumer<Double> callback = value -> {
if (mPoint != null) {
mPointService.sendKafka4OpcUa(mPoint.getId(), value, CommUtil.nowDate());
}
};
opcUaService.subscribeToNode(nodeId, callback);
subscribedNodeIds.add(nodeId); // 记录已订阅的点位
}
System.out.println("Subscribed to " + nodeIdList.size() + " nodes");
} catch (Exception e) {
System.err.println("Failed to subscribe: " + e.getMessage());
}
}
/**
* 同步一次opcua订阅点位
*/
public void manualSyncSubscriptions() {
try {
List<String> currentNodeIds = fetchNodeIdsFromEs(); // 获取当前 Elasticsearch 中的点位信息
Set<String> newSubscribedNodeIds = new HashSet<>();
// 处理新增点位
for (String nodeId : currentNodeIds) {
if (!subscribedNodeIds.contains(nodeId)) { // 新增点位
MPoint mPoint = mPointCache.get(nodeId, key -> mPointService.selectById("",nodeId));
System.out.println(mPoint);
Consumer<Double> callback = value -> {
if (mPoint != null) {
mPointService.sendKafka4OpcUa(mPoint.getId(), value, CommUtil.nowDate());
}
};
opcUaService.subscribeToNode(nodeId, callback);
newSubscribedNodeIds.add(nodeId);
} else {
newSubscribedNodeIds.add(nodeId); // 保留已订阅的点位
}
}
// 处理删除点位
for (String nodeId : subscribedNodeIds) {
if (!currentNodeIds.contains(nodeId)) { // 删除点位
opcUaService.unsubscribeFromNode(nodeId);
}
}
// 更新已订阅点位集合
subscribedNodeIds = newSubscribedNodeIds;
System.out.println("进行一次opcua订阅同步");
} catch (Exception e) {
System.err.println("opcua订阅同步失败: " + e.getMessage());
}
}
/**
* 查询所有的opcua采集点位
*
* @return
*/
private List<String> fetchNodeIdsFromEs() {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
BoolQueryBuilder childBoolQueryBuilder = QueryBuilders.boolQuery();
childBoolQueryBuilder.must(QueryBuilders.matchPhraseQuery("biztype", "opcua"));
boolQueryBuilder.should(childBoolQueryBuilder);
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 10000));
List<MPoint> list_mps = this.mPointService.selectListByWhere4Es(nativeSearchQueryBuilder);
List<String> nodeIdList = new ArrayList<>();
for (MPoint mPoint : list_mps) {
nodeIdList.add(mPoint.getMpointid());
}
return nodeIdList;
}
}

View File

@ -0,0 +1,277 @@
package com.sipai.service.opc;
import com.sipai.config.OpcUaProperties;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
import org.eclipse.milo.opcua.sdk.client.nodes.UaVariableNode;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@Service
public class OpcUaService {
@Autowired(required = false)
private final OpcUaClient opcUaClient;
private final OpcUaProperties opcUaProperties;
@Autowired
public OpcUaService(@Autowired(required = false) OpcUaClient opcUaClient, OpcUaProperties opcUaProperties) {
this.opcUaClient = opcUaClient;
this.opcUaProperties = opcUaProperties;
}
/*public void printConfig() {
System.out.println("OPC UA Server URL: " + opcUaProperties.getServerUrl());
System.out.println("Security Policy: " + opcUaProperties.getSecurityPolicy());
System.out.println("Security Mode: " + opcUaProperties.getSecurityMode());
}*/
/**
* 读取单个点位的值
*
* @param nodeId
* @return
* @throws ExecutionException
* @throws InterruptedException
*/
public Object readNodeValue(String nodeId) throws ExecutionException, InterruptedException {
if (opcUaClient == null) {
throw new IllegalStateException("OPC UA 未启动请检查yml配置文件钟opc: enabled: true");
}
NodeId node = NodeId.parse(nodeId);
DataValue dataValue = opcUaClient.readValue(0, TimestampsToReturn.Both, node).get();
Variant variant = dataValue.getValue();
return variant.getValue();
}
/**
* 写入单个点位的值
*
* @param nodeId 节点ID
* @param value 要写入的值
* @return 写入是否成功
* @throws ExecutionException
* @throws InterruptedException
*/
public boolean writeNodeValue(String nodeId, Object value) {
try {
NodeId node = NodeId.parse(nodeId);
// 读取节点的数据类型(使用 UaVariableNode 替代 VariableNode
UaVariableNode variableNode = (UaVariableNode) opcUaClient.getAddressSpace().getVariableNode(node);
if (variableNode == null) {
throw new RuntimeException("无法找到节点: " + nodeId);
}
NodeId dataTypeId = variableNode.getDataType();
System.out.println(dataTypeId);
if (dataTypeId == null) {
throw new RuntimeException("无法获取节点的数据类型");
}
// 根据数据类型创建对应的 Variant
Variant variant = createVariantForDataType(value, dataTypeId);
DataValue dataValue = DataValue.valueOnly(variant);
StatusCode statusCode = opcUaClient.writeValue(node, dataValue).get();
System.out.println(statusCode);
return statusCode.isGood();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* typeId跟标准规范不一致目前用 KEPServerEX6自带的OPCUA服务 测试的结果
*
* @param value
* @param dataTypeId
* @return
*/
private Variant createVariantForDataType(Object value, NodeId dataTypeId) {
int typeId = ((Number) dataTypeId.getIdentifier()).intValue();
// 标准类型处理
switch (typeId) {
case 1:
return new Variant(convertToBoolean(value));
case 4: // Int16 (有符号short)
short shortValue = (value instanceof Number) ?
((Number) value).shortValue() :
Short.parseShort(value.toString());
return new Variant(shortValue);
case 5: // UInt16/Word (无符号short)
int intValue = (value instanceof Number) ?
((Number) value).intValue() :
Integer.parseInt(value.toString());
if (intValue < 0 || intValue > 65535) {
throw new IllegalArgumentException("UInt16 值必须在 0~65535 之间");
}
return new Variant(Unsigned.ushort(intValue));
case 6: // Int32
return new Variant(convertToInt(value));
case 10: //Float
return new Variant(convertToFloat(value));
case 11: // Double
return new Variant(convertToDouble(value));
default:
return new Variant(value.toString());
}
}
// 类型转换辅助方法(保持不变)
private boolean convertToBoolean(Object value) {
if (value instanceof Boolean) return (Boolean) value;
String strVal = value.toString().trim().toLowerCase();
return strVal.equals("true") || strVal.equals("1");
}
private float convertToFloat(Object value) {
if (value instanceof Number) return ((Number) value).floatValue();
return Float.parseFloat(value.toString());
}
private double convertToDouble(Object value) {
if (value instanceof Number) return ((Number) value).doubleValue();
return Double.parseDouble(value.toString());
}
private int convertToInt(Object value) {
if (value instanceof Number) return ((Number) value).intValue();
return Integer.parseInt(value.toString());
}
private long convertToUInt(Object value) {
if (value instanceof Number) return ((Number) value).longValue();
return Long.parseLong(value.toString());
}
// 订阅点位
public void subscribeToNode(String nodeId, Consumer<Double> callback) throws Exception {
if (opcUaClient == null) {
throw new IllegalStateException("OPC UA 未启动请检查yml配置文件钟opc: enabled: true");
}
try {
NodeId node = NodeId.parse(nodeId);
UaSubscription subscription = opcUaClient
.getSubscriptionManager()
.createSubscription(1000.0)
.get();
MonitoringParameters parameters = new MonitoringParameters(
Unsigned.uint(1),
1000.0,
null,
Unsigned.uint(10),
true
);
MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
new ReadValueId(
node,
AttributeId.Value.uid(),
null,
null
),
MonitoringMode.Reporting,
parameters
);
subscription.createMonitoredItems(
TimestampsToReturn.Both,
Collections.singletonList(request),
new UaSubscription.ItemCreationCallback() {
@Override
public void onItemCreated(UaMonitoredItem item, int i) {
// 设置值的回调处理器
item.setValueConsumer(value -> {
Variant variant = value.getValue();
Object rawValue = variant.getValue();
if (rawValue instanceof Number) {
callback.accept(((Number) rawValue).doubleValue()); // 转为 Double
} else if (rawValue instanceof Boolean) {
callback.accept(((Boolean) rawValue) ? 1.0 : 0.0); // 布尔转0 1
} else {
throw new ClassCastException("Expected Number or Boolean but received: " +
rawValue.getClass().getSimpleName());
}
});
}
}
).get();
} catch (Exception e) {
throw new Exception("订阅失败: " + e.getMessage(), e);
}
}
// 取消订阅点位
public boolean unsubscribeFromNode(String nodeId) {
if (opcUaClient == null) {
throw new IllegalStateException("OPC UA 未启动请检查yml配置文件钟opc: enabled: true");
}
try {
NodeId node = NodeId.parse(nodeId);
// 获取所有订阅
List<UaSubscription> subscriptions = opcUaClient.getSubscriptionManager().getSubscriptions();
for (UaSubscription subscription : subscriptions) {
// 获取所有监控项
List<UaMonitoredItem> monitoredItems = subscription.getMonitoredItems();
for (UaMonitoredItem monitoredItem : monitoredItems) {
if (monitoredItem.getReadValueId().getNodeId().equals(node)) {
// 删除监控项
CompletableFuture<List<StatusCode>> deleteFuture = subscription.deleteMonitoredItems(
Collections.singletonList(monitoredItem)
);
// 等待删除操作完成
List<StatusCode> statusCodes = deleteFuture.get(5, TimeUnit.SECONDS);
// 检查删除结果
for (StatusCode statusCode : statusCodes) {
if (!statusCode.isGood()) {
System.err.println("删除监控项失败: " + statusCode);
return false;
}
}
System.out.println("成功取消订阅节点: " + nodeId);
return true;
}
}
}
System.out.println("未找到节点: " + nodeId);
return false;
} catch (Exception e) {
System.err.println("取消订阅失败: " + e.getMessage());
return false;
}
}
}

Some files were not shown because too many files have changed in this diff Show More