Compare commits

...

6 Commits

Author SHA1 Message Date
35a4e837fb 1.代码优化 2026-01-06 17:19:17 +08:00
cdf
08fcd0c564 代码提交 2024-08-26 11:27:51 +08:00
bfc7884f50 1.添加安全登录功能
2.调整部分接口
2024-08-16 17:16:47 +08:00
9617f3d975 1.添加安全登录功能
2.调整部分接口
2024-08-13 16:14:45 +08:00
7449efc6a3 更改 2024-08-09 09:05:41 +08:00
41f8c873a4 更改 2024-07-30 10:38:40 +08:00
46 changed files with 17302 additions and 334 deletions

94
pom.xml
View File

@@ -55,12 +55,11 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>mqs-client-njcn</artifactId>
@@ -125,6 +124,87 @@
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.5</version>
</dependency>
<!-- 引入org.json所需依赖 -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-plus插件-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.github.jeffreyning</groupId>
<artifactId>mybatisplus-plus</artifactId>
<version>1.5.1-RELEASE</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>pqs-influx</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
@@ -133,16 +213,6 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>

View File

@@ -1,9 +1,16 @@
package com.njcn.roma;
import com.github.jeffreyning.mybatisplus.conf.EnableMPP;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.DependsOn;
@SpringBootApplication
@SpringBootApplication(scanBasePackages = "com.njcn")
@MapperScan("com.njcn.roma.mapper")
@DependsOn("proxyMapperRegister")
@EnableMPP
public class RomaApplication {
public static void main(String[] args) {

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,123 @@
package com.njcn.roma.client;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
public class TestNorthApi {
private static final String ApicHost = "10.10.10.1:1443";
private static final String appId = "roma.link.test";
private static final String appKey = "ic+HsXPRCA****";
private static final String deviceId="D6111KOQk";
//测命令下发时用到的替换成自己的serviceName和commandName
private static final String serviceName="service";
private static final String commandName="command";
/**
* 创建ssl连接设置客户端信任所有证书
* @return CloseableHttpClient
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private static CloseableHttpClient createSSLClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
/**
* 设置请求时的header
* @param httpUriRequest
*/
private static void setSSLHeader(HttpUriRequest httpUriRequest) {
long time = System.currentTimeMillis();
String authorization = DigestUtils.sha256Hex(appId + appKey + time);
httpUriRequest.addHeader("Content-Type", "application/json");
httpUriRequest.addHeader("Authorization", authorization);
httpUriRequest.addHeader("timestamp", String.valueOf(time));
}
/**
* 解析响应结果
* @param httpUriRequest
* @return
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
* @throws IOException
*/
private static HttpEntity getSSLResponse(HttpUriRequest httpUriRequest) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
CloseableHttpClient httpClient = createSSLClient();
CloseableHttpResponse response = httpClient.execute(httpUriRequest);
HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
System.out.println("响应内容长度为:" + responseEntity.getContentLength());
System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
}
return responseEntity;
}
/**
* 命令下发
*
* @param serviceName
* @param commandName
* @param cmdComtent
* @throws JSONException
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
*/
public static void deviceCommands(String serviceName, String commandName, JSONObject cmdComtent) throws JSONException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
String url = "https://" + ApicHost + "/iot/1.0/deviceCommands?appId=" + appId;
HttpPost httpPost = new HttpPost(url); //创建post请求
JSONObject cmdContent = new JSONObject();
cmdContent.put("serviceId", serviceName);
cmdContent.put("method", commandName);
cmdContent.put("paras", cmdComtent);
JSONObject cmdBody = new JSONObject();
cmdBody.put("command", cmdContent);
cmdBody.put("deviceId", deviceId);
setSSLHeader(httpPost); //设置请求的header
StringEntity stringEntity = new StringEntity(cmdBody.toString(), "utf-8");
httpPost.setEntity(stringEntity);//设置请求的body
getSSLResponse(httpPost);//获取响应结果
}
public static void main(String[] args) throws Exception {
JSONObject commandContent = new JSONObject();
commandContent.put("status", "on");
deviceCommands(serviceName, commandName, commandContent);
}
}

View File

@@ -35,4 +35,8 @@ public class RestTemplateConfig {
return factory;
}
}

View File

@@ -0,0 +1,19 @@
package com.njcn.roma.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class Security extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().authorizeRequests().anyRequest().authenticated().and().csrf().disable();
}
}

View File

@@ -0,0 +1,17 @@
package com.njcn.roma.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 用于扫描和注册所有携带ServerEndPoint注解的实例。
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@@ -0,0 +1,183 @@
package com.njcn.roma.controller;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
/**
* roma
* 设备台账控制
* @author cdf
* @date 2024/8/21
*/
@RestController
@RequiredArgsConstructor
public class DeviceController {
@Value("${roma.acceptIp}")
private String acceptIp;
@Value("${roma.sendIp}")
private String sendIp;
@Value("${roma.appId}")
private String appId;
@Value("${roma.appKey}")
private String appKey;
/**
* 查询设备信息
* @author cdf
* @date 2024/8/21
*/
@GetMapping("queryDevice")
public String queryDeviceById(@RequestParam String devId){
try {
queryDeviceInfo(devId);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return "获取成功";
}
/**
* 查询告警信息
* @author cdf
* @date 2024/8/21
*/
@GetMapping("alarmHistory")
public String alarmHistory(@RequestParam String devId){
try {
queryAlarm(devId);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return "获取成功";
}
/**
* 查询设备信息
*
* @throws JSONException
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
*/
public void queryDeviceInfo(String deviceId) throws NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
String url = "https://" + sendIp + "/iot/1.0/devices?deviceId="+deviceId+"&appId=" + appId;
// /iot/1.0/devices?deviceId={deviceId}&appId={appId}
HttpGet httpGet = new HttpGet(url); //创建post请求
setSSLHeader(httpGet); //设置请求的header
getSSLResponse(httpGet);//获取响应结果
}
public void queryAlarm(String deviceId) throws NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
String url = "https://" + sendIp + "/iot/1.0/devices?deviceId="+deviceId+"&appId=" + appId;
// /iot/1.0/devices?deviceId={deviceId}&appId={appId}
HttpGet httpGet = new HttpGet(url); //创建post请求
setSSLHeader(httpGet); //设置请求的header
getSSLResponse(httpGet);//获取响应结果
}
/**
* 创建ssl连接设置客户端信任所有证书
* @return CloseableHttpClient
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private CloseableHttpClient createSSLClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
/**
* 设置请求时的header
* @param httpUriRequest
*/
private void setSSLHeader(HttpUriRequest httpUriRequest) {
long time = System.currentTimeMillis();
String authorization = DigestUtils.sha256Hex(appId + appKey + time);
httpUriRequest.addHeader("Content-Type", "application/json");
httpUriRequest.addHeader("Authorization", authorization);
httpUriRequest.addHeader("timestamp", String.valueOf(time));
}
/**
* 解析响应结果
* @param httpUriRequest
* @return
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
* @throws IOException
*/
private org.apache.http.HttpEntity getSSLResponse(HttpUriRequest httpUriRequest) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
CloseableHttpClient httpClient = createSSLClient();
CloseableHttpResponse response = httpClient.execute(httpUriRequest);
org.apache.http.HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
System.out.println("响应内容长度为:" + responseEntity.getContentLength());
System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
}
return responseEntity;
}
}

View File

@@ -1,10 +1,23 @@
package com.njcn.roma.controller;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSONObject;
import com.njcn.roma.pojo.CommandDTO;
import com.njcn.roma.pojo.UpSendPojo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
@@ -12,9 +25,18 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;
@@ -49,45 +71,148 @@ public class SendCommandController {
* @date 2024/6/25
*/
@GetMapping("up")
public String sendToDev(){
String time = String.valueOf(new Date().getTime());
String sha = DigestUtil.sha256Hex(appId+appKey+time);
System.out.println("加密秘钥"+sha);
// 请求头信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf("application/json;charset=UTF-8"));
headers.add("timestamp",time);
headers.add("Authorization",sha);
// 请求体内容
UpSendPojo param = new UpSendPojo();
param.setDeviceId("666666");
CommandDTO commandDTO = new CommandDTO();
JSONObject jsonObject = new JSONObject();
jsonObject.put("","");
commandDTO.setJsonObject(jsonObject);
commandDTO.setServiceId("123");
commandDTO.setMethod("aaa");
param.setCommandDTO(commandDTO);
// 组装请求信息
HttpEntity<UpSendPojo> httpEntity=new HttpEntity<>(param,headers);
System.out.println(httpEntity.getHeaders());
System.out.println(httpEntity.getBody());
ResponseEntity responseEntity = restTemplate.postForEntity(sendIp,httpEntity,String.class);
System.out.println("返回状态:"+ responseEntity.getStatusCode());
return Objects.requireNonNull(responseEntity.getBody()).toString();
public String sendToDev(@RequestParam("serviceId")String serviceId,@RequestParam("method")String method,@RequestParam(value = "deviceId",defaultValue = "D2899233167kupZT")String deviceId){
org.json.JSONObject commandContent = new JSONObject();
commandContent.put("status", "on");
try {
deviceCommands(deviceId,serviceId,method,commandContent);
} catch (IOException e) {
System.out.println("IOException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (KeyStoreException e) {
System.out.println("KeyStoreException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (KeyManagementException e) {
System.out.println("KeyManagementException---------------------------");
e.printStackTrace();
return e.getMessage();
}catch (Exception e){
System.out.println("Exception---------------------------");
e.printStackTrace();
return e.getMessage();
}
return "执行成功";
}
@GetMapping("test")
public String test(){
return "6666";
@GetMapping("queryService")
public String test(@RequestParam(value = "deviceId",defaultValue = "D2899233167kupZT")String deviceId){
//String url = "https://" + sendIp + "/iot/1.0/deviceCommands?appId=" + appId;
String url = "https://" + sendIp + "/iot/1.0/services?appId=" + appId+"&deviceId="+deviceId;
HttpGet httpGet = new HttpGet(url); //创建post请求
setSSLHeader(httpGet); //设置请求的header
try {
org.apache.http.HttpEntity responseEntity = getSSLResponse(httpGet);//获取响应结果
return EntityUtils.toString(responseEntity);
} catch (IOException e) {
System.out.println("IOException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (KeyStoreException e) {
System.out.println("KeyStoreException---------------------------");
e.printStackTrace();
return e.getMessage();
} catch (KeyManagementException e) {
System.out.println("KeyManagementException---------------------------");
e.printStackTrace();
return e.getMessage();
}catch (Exception e){
System.out.println("Exception---------------------------");
e.printStackTrace();
return e.getMessage();
}
}
/**
* 创建ssl连接设置客户端信任所有证书
* @return CloseableHttpClient
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private CloseableHttpClient createSSLClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
/**
* 设置请求时的header
* @param httpUriRequest
*/
private void setSSLHeader(HttpUriRequest httpUriRequest) {
long time = System.currentTimeMillis();
String authorization = DigestUtils.sha256Hex(appId + appKey + time);
httpUriRequest.addHeader("Content-Type", "application/json");
httpUriRequest.addHeader("Authorization", authorization);
httpUriRequest.addHeader("timestamp", String.valueOf(time));
}
/**
* 解析响应结果
* @param httpUriRequest
* @return
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
* @throws IOException
*/
private org.apache.http.HttpEntity getSSLResponse(HttpUriRequest httpUriRequest) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
CloseableHttpClient httpClient = createSSLClient();
CloseableHttpResponse response = httpClient.execute(httpUriRequest);
org.apache.http.HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
System.out.println("响应内容长度为:" + responseEntity.getContentLength());
System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
}
return responseEntity;
}
/**
* 命令下发
*
* @param serviceName
* @param commandName
* @param cmdComtent
* @throws JSONException
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
*/
public void deviceCommands(String deviceId,String serviceName, String commandName, org.json.JSONObject cmdComtent) throws JSONException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
String url = "https://" + sendIp + "/iot/1.0/deviceCommands?appId=" + appId;
HttpPost httpPost = new HttpPost(url); //创建post请求
org.json.JSONObject cmdContent = new org.json.JSONObject();
cmdContent.put("serviceId", serviceName);
cmdContent.put("method", commandName);
cmdContent.put("paras", cmdComtent);
org.json.JSONObject cmdBody = new org.json.JSONObject();
cmdBody.put("command", cmdContent);
cmdBody.put("deviceId", deviceId);
setSSLHeader(httpPost); //设置请求的header
StringEntity stringEntity = new StringEntity(cmdBody.toString(), "utf-8");
httpPost.setEntity(stringEntity);//设置请求的body
getSSLResponse(httpPost);//获取响应结果
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,15 +1,47 @@
package com.njcn.roma.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huawei.it.eip.ump.client.producer.Producer;
import com.huawei.it.eip.ump.client.producer.SendResult;
import com.huawei.it.eip.ump.common.exception.UmpException;
import com.huawei.it.eip.ump.common.message.Message;
import com.njcn.influx.imapper.DataHarmPowerPMapper;
import com.njcn.influx.imapper.DataHarmRateVMapper;
import com.njcn.influx.imapper.DataVMapper;
import com.njcn.influx.pojo.po.DataHarmPowerP;
import com.njcn.influx.pojo.po.DataHarmRateV;
import com.njcn.influx.pojo.po.DataV;
import com.njcn.roma.client.ClientHandler;
import com.njcn.roma.mapper.EleEpdPqdMapper;
import com.njcn.roma.pojo.EleEpdPqd;
import com.njcn.roma.pojo.MonitorRealData;
import com.njcn.roma.server.WebSocketServer;
import com.njcn.roma.service.MonitorRealDataService;
import com.njcn.roma.utils.JsonValueFluctuator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* roma
@@ -19,10 +51,30 @@ import java.io.UnsupportedEncodingException;
*/
@RestController
@RequiredArgsConstructor
@Slf4j
public class TestController {
private final ClientHandler clientHandler;
private final WebSocketServer webSocketServer;
public String topicMsg = "{\"DataType\":\"1.000\",\"HRPhV_H14_phsC\":\"0.2000\",\"HRPhV_H14_phsB\":\"0.0000\",\"HRPhV_H14_phsA\":\"0.0000\",\"HRPhV_H2_phsB\":\"0.0100\",\"HRPhV_H2_phsA\":\"0.0100\",\"HRPhV_H2_phsC\":\"0.0100\",\"HRPhV_H15_phsA\":\"0.0120\",\"TotW\":\"19771.1367\",\"HRPhV_H15_phsB\":\"0.0120\",\"HRPhV_H15_phsC\":\"0.0120\",\"FreqDev\":\"0.0000\",\"PPV_phsAB\":\"384.0318\",\"A_phsC\":\"60.7116\",\"TotPF\":\"0.4946\",\"A_phsA\":\"60.7123\",\"A_phsB\":\"60.7111\",\"PPV_phsBC\":\"383.3656\",\"HRPhV_H25_phsB\":\"0.0080\",\"HRPhV_H25_phsC\":\"0.0080\",\"HRPhV_H25_phsA\":\"0.0080\",\"DataTag\":\"0\",\"HRPhV_H20_phsA\":\"0.0000\",\"HRPhV_H20_phsB\":\"0.0000\",\"HRPhV_H20_phsC\":\"0.0000\",\"PPV_phsCA\":\"383.3637\",\"HRPhV_H3_phsB\":\"0.0640\",\"HRPhV_H3_phsC\":\"0.0640\",\"HRPhV_H9_phsC\":\"0.0220\",\"ThdPhV_phsA\":\"0.0913\",\"HRPhV_H9_phsB\":\"0.0220\",\"HRPhV_H9_phsA\":\"0.0220\",\"ThdPhV_phsB\":\"0.0913\",\"ThdPhV_phsC\":\"0.0913\",\"HRPhV_H19_phsC\":\"0.0100\",\"HRPhV_H19_phsB\":\"0.0100\",\"HRPhV_H19_phsA\":\"0.0100\",\"HRPhV_H16_phsA\":\"0.0000\",\"HRPhV_H13_phsA\":\"0.0140\",\"HRPhV_H16_phsC\":\"0.0000\",\"HRPhV_H13_phsB\":\"0.0140\",\"HRPhV_H16_phsB\":\"0.0000\",\"TotVA\":\"39977.2305\",\"HRPhV_H13_phsC\":\"0.0140\",\"HRPhV_H6_phsB\":\"0.0026\",\"HRPhV_H3_phsA\":\"0.0640\",\"HRPhV_H6_phsA\":\"0.0026\",\"HRPhV_H10_phsA\":\"0.0026\",\"HRPhV_H10_phsB\":\"0.0026\",\"HRPhV_H6_phsC\":\"0.0026\",\"HRPhV_H10_phsC\":\"0.0026\",\"ImbNgV\":\"0.0012\",\"TotVar\":\"34745.9492\",\"HRPhV_H7_phsC\":\"0.0280\",\"HRPhV_H7_phsB\":\"0.0280\",\"HRPhV_H22_phsC\":\"0.0000\",\"HRPhV_H22_phsB\":\"0.0000\",\"ImbZroV\":\"0.0012\",\"HRPhV_H22_phsA\":\"0.0000\",\"HRPhV_H7_phsA\":\"0.0280\",\"HRPhV_H8_phsA\":\"0.0026\",\"HRPhV_H23_phsB\":\"0.0080\",\"PhV_phsA\":\"221.9935\",\"HRPhV_H8_phsB\":\"0.0026\",\"HRPhV_H23_phsC\":\"0.0080\",\"HRPhV_H8_phsC\":\"0.0026\",\"PhV_phsB\":\"221.9947\",\"PhV_phsC\":\"221.9979\",\"HRPhV_H23_phsA\":\"0.0080\",\"PstPhV_phsC\":\"3.2942\",\"PstPhV_phsA\":\"3.3086\",\"PstPhV_phsB\":\"3.2987\",\"Freq\":\"50.0000\",\"HRPhV_H11_phsA\":\"0.0180\",\"HRPhV_H11_phsB\":\"0.0180\",\"HRPhV_H17_phsC\":\"0.0100\",\"HRPhV_H11_phsC\":\"0.0180\",\"HRPhV_H17_phsB\":\"0.0100\",\"HRPhV_H17_phsA\":\"0.0100\",\"SeqV_C2\":\"0.0715\",\"HRPhV_H4_phsB\":\"0.0050\",\"SeqV_C1\":\"60.4601\",\"HRPhV_H4_phsA\":\"0.0050\",\"SeqV_C0\":\"0.0714\",\"PhVDev_phsC\":\"0.0119\",\"HRPhV_H5_phsA\":\"0.0400\",\"HRPhV_H5_phsB\":\"0.0400\",\"HRPhV_H5_phsC\":\"0.0400\",\"PhVDev_phsB\":\"0.0119\",\"HRPhV_H12_phsC\":\"0.0010\",\"PltPhV_phsA\":\"0.0000\",\"PhVDev_phsA\":\"0.0119\",\"HRPhV_H12_phsB\":\"0.0010\",\"HRPhV_H4_phsC\":\"0.0050\",\"HRPhV_H18_phsB\":\"0.0000\",\"HRPhV_H18_phsC\":\"0.0000\",\"HRPhV_H12_phsA\":\"0.0010\",\"HRPhV_H18_phsA\":\"0.0000\",\"HFundPhV_phsC\":\"220.8052\",\"HRPhV_H21_phsC\":\"0.0080\",\"HRPhV_H21_phsB\":\"0.0080\",\"HRPhV_H24_phsC\":\"0.0000\",\"HFundPhV_phsA\":\"220.8056\",\"HRPhV_H21_phsA\":\"0.0080\",\"HFundPhV_phsB\":\"220.8055\",\"HRPhV_H24_phsB\":\"0.0000\",\"PltPhV_phsC\":\"0.0000\",\"HRPhV_H24_phsA\":\"0.0000\",\"PltPhV_phsB\":\"0.0000\",\"time\":\"20241115T150000Z\"}";
public String devId = "暂无数据";
private final EleEpdPqdMapper eleEpdPqdMapper;
private final DataVMapper dataVMapper;
private final DataHarmRateVMapper dataHarmRateVMapper;
private final DataHarmPowerPMapper dataHarmPowerPMapper;
private final MonitorRealDataService monitorRealDataService;
private final String idKey = "pmswifi_";
@GetMapping("send")
@@ -75,23 +127,260 @@ public class TestController {
}
/**
* 启动客户端
*
* @author cdf
* @date 2024/7/1
*/
@GetMapping("clientTest")
public void TestClient() {
clientHandler.start();
System.out.println("进入模拟程序调用--------------------");
String topic = "{\"HRPhV_H14_phsC\":0.078,\"HRPhV_H14_phsB\":0.035,\"HRPhV_H14_phsA\":0.044,\"HRPhV_H2_phsB\":0.132,\"HRPhV_H2_phsA\":0.141,\"HRPhV_H2_phsC\":0.158,\"HRPhV_H15_phsA\":0.121,\"TotW\":15877.469,\"HRPhV_H15_phsB\":0.155,\"HRPhV_H15_phsC\":0.342,\"FreqDev\":0.034,\"PPV_phsAB\":407.071,\"A_phsC\":28.514,\"TotPF\":0.996,\"A_phsA\":20.083,\"A_phsB\":29.695,\"PPV_phsBC\":408.577,\"HRPhV_H25_phsB\":0.046,\"HRPhV_H25_phsC\":0.039,\"HRPhV_H25_phsA\":0.052,\"DataTag\":\"0.000\",\"HRPhV_H20_phsA\":0.102,\"HRPhV_H20_phsB\":0.085,\"HRPhV_H20_phsC\":0.126,\"DataType\":\"CP95\",\"PPV_phsCA\":408.532,\"HRPhV_H3_phsB\":0.544,\"HRPhV_H3_phsC\":0.432,\"HRPhV_H9_phsC\":0.195,\"ThdPhV_phsA\":1.408,\"HRPhV_H9_phsB\":0.271,\"HRPhV_H9_phsA\":0.21,\"ThdPhV_phsB\":1.453,\"ThdPhV_phsC\":1.688,\"HRPhV_H19_phsC\":0.095,\"HRPhV_H19_phsB\":0.171,\"HRPhV_H19_phsA\":0.086,\"HRPhV_H16_phsA\":0.312,\"HRPhV_H13_phsA\":0.295,\"HRPhV_H16_phsC\":0.408,\"HRPhV_H13_phsB\":0.245,\"HRPhV_H16_phsB\":0.215,\"TotVA\":16013.368,\"HRPhV_H13_phsC\":0.394,\"HRPhV_H6_phsB\":0.088,\"HRPhV_H3_phsA\":0.246,\"HRPhV_H6_phsA\":0.042,\"HRPhV_H10_phsA\":0.056,\"HRPhV_H10_phsB\":0.038,\"HRPhV_H6_phsC\":0.083,\"HRPhV_H10_phsC\":0.068,\"ImbNgV\":0.465,\"TotVar\":-191.2,\"HRPhV_H7_phsC\":1.019,\"HRPhV_H7_phsB\":0.801,\"HRPhV_H22_phsC\":0.064,\"HRPhV_H22_phsB\":0.041,\"ImbZroV\":0.05,\"HRPhV_H22_phsA\":0.035,\"HRPhV_H7_phsA\":0.855,\"HRPhV_H8_phsA\":0.061,\"HRPhV_H23_phsB\":0.039,\"PhV_phsA\":235.764,\"HRPhV_H8_phsB\":0.041,\"HRPhV_H23_phsC\":0.111,\"HRPhV_H8_phsC\":0.075,\"PhV_phsB\":235.669,\"PhV_phsC\":236.598,\"HRPhV_H23_phsA\":0.114,\"PstPhV_phsC\":0.172,\"PstPhV_phsA\":0.177,\"PstPhV_phsB\":0.182,\"Freq\":50.034,\"HRPhV_H11_phsA\":0.265,\"HRPhV_H11_phsB\":0.246,\"HRPhV_H17_phsC\":0.199,\"HRPhV_H11_phsC\":0.182,\"HRPhV_H17_phsB\":0.197,\"HRPhV_H17_phsA\":0.248,\"SeqV_C2\":1.092,\"HRPhV_H4_phsB\":0.078,\"SeqV_C1\":235.958,\"HRPhV_H4_phsA\":0.092,\"SeqV_C0\":0.118,\"PhVDev_phsC\":7.842,\"HRPhV_H5_phsA\":0.969,\"HRPhV_H5_phsB\":1.043,\"HRPhV_H5_phsC\":1.097,\"PhVDev_phsB\":7.419,\"HRPhV_H12_phsC\":0.122,\"PltPhV_phsA\":0.255,\"PhVDev_phsA\":7.462,\"HRPhV_H12_phsB\":0.069,\"HRPhV_H4_phsC\":0.132,\"HRPhV_H18_phsB\":0.028,\"HRPhV_H18_phsC\":0.094,\"HRPhV_H12_phsA\":0.105,\"HRPhV_H18_phsA\":0.052,\"HFundPhV_phsC\":236.564,\"HRPhV_H21_phsC\":0.096,\"HRPhV_H21_phsB\":0.083,\"HRPhV_H24_phsC\":0.052,\"HFundPhV_phsA\":235.737,\"HRPhV_H21_phsA\":0.071,\"HFundPhV_phsB\":235.64,\"HRPhV_H24_phsB\":0.032,\"PltPhV_phsC\":0.244,\"HRPhV_H24_phsA\":0.032,\"PltPhV_phsB\":0.242,\"time\":\"2025-09-23T08:23:00Z\"}";
String topic2 = "{\"time\":\"20260106T170100Z\",\"DataTag\":0,\"DataType\":\"1.000\",\"Freq\":50.0671,\"FreqDev\":0.0671,\"A_phsA\":104.2118,\"A_phsB\":103.4132,\"A_phsC\":102.7066,\"PhV_phsA\":5.0094,\"PhV_phsB\":5.0081,\"PhV_phsC\":4.9913,\"PPV_phsAB\":8.68,\"PPV_phsBC\":8.6621,\"PPV_phsCA\":8.6539,\"PhVDev_phsA\":-13.2348,\"PhVDev_phsB\":-13.2564,\"PhVDev_phsC\":-13.5473,\"TotW\":1537.62427,\"TotVA\":1537.63232,\"TotVar\":5.0479,\"TotPF\":1,\"SeqV_C1\":4990.753,\"SeqV_C2\":0.0089,\"SeqV_C0\":0.0047,\"ImbNgV\":0.1785,\"ImbZroV\":0.0938,\"HFundPhV_phsA\":4.9972,\"HFundPhV_phsB\":4.9959,\"HFundPhV_phsC\":4.9792,\"ThdPhV_phsA\":6.9898,\"ThdPhV_phsB\":7.0035,\"ThdPhV_phsC\":6.98,\"HRPhV_H2_phsA\":0.9546,\"HRPhV_H3_phsA\":1.006,\"HRPhV_H4_phsA\":1.0045,\"HRPhV_H5_phsA\":0.9977,\"HRPhV_H6_phsA\":1.0003,\"HRPhV_H7_phsA\":0.9975,\"HRPhV_H8_phsA\":1,\"HRPhV_H9_phsA\":1.0008,\"HRPhV_H10_phsA\":1.0013,\"HRPhV_H11_phsA\":1.0002,\"HRPhV_H12_phsA\":1.003,\"HRPhV_H13_phsA\":1.0022,\"HRPhV_H14_phsA\":1.0027,\"HRPhV_H15_phsA\":1.0033,\"HRPhV_H16_phsA\":1.0017,\"HRPhV_H17_phsA\":1.0019,\"HRPhV_H18_phsA\":1.0012,\"HRPhV_H19_phsA\":1.0012,\"HRPhV_H20_phsA\":1.0008,\"HRPhV_H21_phsA\":1.0007,\"HRPhV_H22_phsA\":1.0028,\"HRPhV_H23_phsA\":1.0027,\"HRPhV_H24_phsA\":1.0054,\"HRPhV_H25_phsA\":1.005,\"HRPhV_H2_phsB\":0.9687,\"HRPhV_H3_phsB\":1.0166,\"HRPhV_H4_phsB\":1.0027,\"HRPhV_H5_phsB\":1.0037,\"HRPhV_H6_phsB\":1.0016,\"HRPhV_H7_phsB\":1.0031,\"HRPhV_H8_phsB\":1.0017,\"HRPhV_H9_phsB\":1.0002,\"HRPhV_H10_phsB\":1.0025,\"HRPhV_H11_phsB\":1.0033,\"HRPhV_H12_phsB\":1.0042,\"HRPhV_H13_phsB\":1.0041,\"HRPhV_H14_phsB\":1.004,\"HRPhV_H15_phsB\":1.0037,\"HRPhV_H16_phsB\":1.0031,\"HRPhV_H17_phsB\":1.0029,\"HRPhV_H18_phsB\":1.0022,\"HRPhV_H19_phsB\":1.0021,\"HRPhV_H20_phsB\":1.0009,\"HRPhV_H21_phsB\":1.0031,\"HRPhV_H22_phsB\":1.004,\"HRPhV_H23_phsB\":1.0048,\"HRPhV_H24_phsB\":1.007,\"HRPhV_H25_phsB\":1.0071,\"HRPhV_H2_phsC\":1.0017,\"HRPhV_H3_phsC\":1.0041,\"HRPhV_H4_phsC\":1.0002,\"HRPhV_H5_phsC\":1.0004,\"HRPhV_H6_phsC\":0.9988,\"HRPhV_H7_phsC\":1.0015,\"HRPhV_H8_phsC\":0.9986,\"HRPhV_H9_phsC\":0.9988,\"HRPhV_H10_phsC\":0.9983,\"HRPhV_H11_phsC\":0.9977,\"HRPhV_H12_phsC\":0.9968,\"HRPhV_H13_phsC\":0.997,\"HRPhV_H14_phsC\":0.9965,\"HRPhV_H15_phsC\":0.9986,\"HRPhV_H16_phsC\":0.9998,\"HRPhV_H17_phsC\":1.0023,\"HRPhV_H18_phsC\":1.0027,\"HRPhV_H19_phsC\":1.0034,\"HRPhV_H20_phsC\":1.0031,\"HRPhV_H21_phsC\":1,\"HRPhV_H22_phsC\":1,\"HRPhV_H23_phsC\":0.9984,\"HRPhV_H24_phsC\":0.996,\"HRPhV_H25_phsC\":0.996,\"PstPhV_phsA\":0,\"PstPhV_phsB\":0,\"PstPhV_phsC\":0,\"PltPhV_phsA\":0,\"PltPhV_phsB\":0,\"PltPhV_phsC\":0}";
String customDevId = "pmswifi_test";
String devId = "deviceIdtest";
clientHandler.dataCalculate(topic2,customDevId,devId);
log.info("模拟成功----------------------");
}
@GetMapping("list")
public List<JSONObject> list(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime, @RequestParam("devId") String devId) {
String sql = "select content from pms_history_data where dev_id ='" + devId + "' and time between '" + startTime + "' and '" + endTime + "'";
List<String> list = new ArrayList<>(); //= this.jdbcTemplate.queryForList(sql, String.class);
List<JSONObject> jsonObjectList = new ArrayList<>();
list.forEach(item -> jsonObjectList.add(JSONObject.parseObject(item)));
return jsonObjectList;
}
@GetMapping("show")
public String show() {
return clientHandler.topicMsg +" >>>>>>> "+ clientHandler.devId;
@GetMapping("simulationWebSocket")
public String simulationWebSocket() {
devId = "NJCN230497";
// 浮动范围比如我们希望数值在原始值的基础上最多变化10%
double fluctuationRange = 0.10;
// 创建Random实例
Random random = new Random();
for (int i = 0; i < 30; i++) {
JSONObject map = JSONObject.parseObject(topicMsg);
map.put("customDevId", devId);
double vA = Double.valueOf(map.get("PhV_phsA").toString());
double vB = Double.valueOf(map.get("PhV_phsB").toString());
double vC = Double.valueOf(map.get("PhV_phsC").toString());
// 生成浮动值
// 注意因为我们要的是百分比所以我们将fluctuationRange乘以originalValue得到最大浮动的绝对值
double fluctuationA = (random.nextDouble() * 2 - 1) * (fluctuationRange * vA);
// 计算新的数值
double newValueA = vA + fluctuationA;
double fluctuationB = (random.nextDouble() * 2 - 1) * (fluctuationRange * vB);
// 计算新的数值
double newValueB = vA + fluctuationB;
double fluctuationC = (random.nextDouble() * 2 - 1) * (fluctuationRange * vC);
// 计算新的数值
double newValueC = vC + fluctuationC;
map.put("PhV_phsA", String.valueOf(newValueA));
map.put("PhV_phsB", String.valueOf(newValueB));
map.put("PhV_phsC", String.valueOf(newValueC));
double iA = Double.valueOf(map.get("A_phsA").toString());
double iB = Double.valueOf(map.get("A_phsB").toString());
double iC = Double.valueOf(map.get("A_phsC").toString());
// 生成浮动值
// 注意因为我们要的是百分比所以我们将fluctuationRange乘以originalValue得到最大浮动的绝对值
double fluctuationIA = (random.nextDouble() * 2 - 1) * (fluctuationRange * vA);
// 计算新的数值
double newValueIA = iA + fluctuationIA;
double fluctuationIB = (random.nextDouble() * 2 - 1) * (fluctuationRange * iB);
// 计算新的数值
double newValueIB = iA + fluctuationIB;
double fluctuationIC = (random.nextDouble() * 2 - 1) * (fluctuationRange * iC);
// 计算新的数值
double newValueIC = iC + fluctuationIC;
map.put("A_phsA", String.valueOf(newValueIA));
map.put("A_phsB", String.valueOf(newValueIB));
map.put("A_phsC", String.valueOf(newValueIC));
String time = map.get("time").toString();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");
try {
ZonedDateTime dateTime = ZonedDateTime.parse(time, formatter);
long aa = 1000 - i;
System.out.println(aa);
dateTime = dateTime.minusMinutes(aa);
String ten = dateTime.format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
System.out.println(ten);
map.put("time", ten);
webSocketServer.sendSocketMessageToAll(map.toJSONString());
/* try {
PmsHistoryDataPO pmsHistoryDataPO = new PmsHistoryDataPO();
pmsHistoryDataPO.setTime(ten);
pmsHistoryDataPO.setDevId(devId);
pmsHistoryDataPO.setContent(map.toJSONString());
pmsHistoryDataMapper.insert(pmsHistoryDataPO);
//int ret = jdbcTemplate.update();
}catch (Exception e){
System.out.println("执行sql语句错误"+e.getMessage());
}*/
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
//Thread.sleep(180000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return "推送成功";
}
@GetMapping("simulationInfluxdb")
@DS("master")
public String simulationInfluxdb() {
System.out.println("进入模拟数据生成接口++++++++++++++++++++++++++++++++++++++++");
List<EleEpdPqd> eleEpdPqdList = eleEpdPqdMapper.selectList(new LambdaQueryWrapper<EleEpdPqd>().eq(EleEpdPqd::getSystemType, "pms"));
Map<String, List<EleEpdPqd>> classMap = eleEpdPqdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getClassId));
//Map<String, EleEpdPqd> eleEpdPqdMap = eleEpdPqdList.stream().collect(Collectors.toMap(EleEpdPqd::getName, Function.identity()));
devId = "NJCN230497111";
for (int j = 0; j < 6; j++) {
List<DataV> poList = new ArrayList<>();
List<DataHarmRateV> dataHarmRateVList = new ArrayList<>();
List<DataHarmPowerP> dataHarmPowerPList = new ArrayList<>();
Instant instant = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();
for (int i = 0; i < 4; i++) {
JSONObject jsonObject = JsonValueFluctuator.fluctuateValuesInJson(topicMsg);
jsonObject.put("customDevId", devId);
if (i == 0) {
jsonObject.put("DataType", "MAX");
} else if (i == 1) {
jsonObject.put("DataType", "MIN");
} else if (i == 2) {
jsonObject.put("DataType", "AVG");
} else if (i == 3) {
jsonObject.put("DataType", "CP95");
}
String lineId = idKey + jsonObject.get("customDevId").toString();
MonitorRealData monitorRealData = new MonitorRealData();
monitorRealData.setLineId(lineId);
monitorRealData.setId(IdUtil.simpleUUID());
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
monitorRealData.setTimeId(localDateTime);
monitorRealData.setValueType(jsonObject.get("DataType").toString());
monitorRealData.setPmsContent(jsonObject.toJSONString());
monitorRealDataService.saveOrUpdateByMultiId(monitorRealData);
classMap.forEach((classId, classList) -> {
Map<String, List<EleEpdPqd>> elePhaseMap = classList.stream().collect(Collectors.groupingBy(EleEpdPqd::getPhase));
elePhaseMap.forEach((phase, list) -> {
Map<String, EleEpdPqd> m = list.stream().collect(Collectors.toMap(EleEpdPqd::getName, Function.identity()));
Map<String, Double> map = new HashMap<>();
m.forEach((mk, mv) -> {
if (jsonObject.containsKey(mk)) {
if (StrUtil.isNotBlank(mv.getOtherName())) {
map.put(mv.getOtherName(), Double.valueOf(jsonObject.get(mk).toString()));
}
}
});
if (classId.equals("data_v")) {
DataV dataV = new DataV();
BeanUtil.copyProperties(map, dataV);
dataV.setPhaseType(phase);
dataV.setLineId(lineId);
dataV.setValueType(jsonObject.get("DataType").toString());
dataV.setQualityFlag("0");
dataV.setTime(instant);
JsonValueFluctuator.setNullNumberFieldsToZero(dataV);
poList.add(dataV);
} else if (classId.equals("data_harmrate_v")) {
DataHarmRateV dataHarmRateV = new DataHarmRateV();
BeanUtil.copyProperties(map, dataHarmRateV);
dataHarmRateV.setPhaseType(phase);
dataHarmRateV.setLineId(lineId);
dataHarmRateV.setValueType(jsonObject.get("DataType").toString());
dataHarmRateV.setQualityFlag("0");
dataHarmRateV.setTime(instant);
JsonValueFluctuator.setNullNumberFieldsToZero(dataHarmRateV);
dataHarmRateVList.add(dataHarmRateV);
} else if (classId.equals("data_harmpower_p")) {
DataHarmPowerP dataHarmPowerP = new DataHarmPowerP();
BeanUtil.copyProperties(map, dataHarmPowerP);
dataHarmPowerP.setPhaseType(phase);
dataHarmPowerP.setLineId(lineId);
dataHarmPowerP.setValueType(jsonObject.get("DataType").toString());
dataHarmPowerP.setQualityFlag("0");
dataHarmPowerP.setTime(instant);
JsonValueFluctuator.setNullNumberFieldsToZero(dataHarmPowerP);
dataHarmPowerPList.add(dataHarmPowerP);
}
});
});
}
try {
dataVMapper.insertBatch(poList);
dataHarmRateVMapper.insertBatch(dataHarmRateVList);
dataHarmPowerPMapper.insertBatch(dataHarmPowerPList);
System.out.println(instant.toString() + ">>>>>>>>>>>模拟数据至influxdb成功");
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(60000);
//Thread.sleep(180000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return "模拟成功";
}
@GetMapping("createTable")
public String createTable() {
String ddl = "CREATE TABLE \"pms_history_data\" (\n" +
" \"time\" text(16) NOT NULL,\n" +
" \"dev_id\" text(10) NOT NULL,\n" +
" \"content\" text NOT NULL,\n" +
" PRIMARY KEY (\"time\", \"dev_id\")\n" +
");";
return "创建pms_history_data成功";
}
}

View File

@@ -24,8 +24,6 @@ public class ClientListener {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
log.info("启动时自动执行 @EventListener 注解方法");
clientHandler.start();
}
}

View File

@@ -0,0 +1,22 @@
package com.njcn.roma.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.roma.pojo.EleEpdPqd;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author xuyang
* @since 2023-05-24
*/
public interface EleEpdPqdMapper extends BaseMapper<EleEpdPqd> {
}

View File

@@ -0,0 +1,14 @@
package com.njcn.roma.mapper;
import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
import com.njcn.roma.pojo.MonitorRealData;
import org.apache.ibatis.annotations.Mapper;
/**
* roma
*
* @author cdf
* @date 2024/8/25
*/
public interface MonitorRealDataMapper extends MppBaseMapper<MonitorRealData> {
}

View File

@@ -0,0 +1,7 @@
//package com.njcn.roma.mapper;
//
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.njcn.roma.pojo.PmsHistoryDataPO;
//
//public interface PmsHistoryDataMapper extends BaseMapper<PmsHistoryDataPO> {
//}

View File

@@ -17,4 +17,7 @@ public class CommandDTO {
private String method;
private JSONObject jsonObject;
}

View File

@@ -0,0 +1,170 @@
package com.njcn.roma.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* <p>
*
* </p>
*
* @author xuyang
* @since 2023-05-24
*/
@Data
@TableName("ele_epd_pqd")
public class EleEpdPqd {
private static final long serialVersionUID = 1L;
/**
* Id
*/
private String id;
/**
* 数据名称
*/
private String name;
/**
* 别名
*/
private String otherName;
/**
* 展示
*/
private String showName;
/**
* 数据编号
*/
private Integer sort;
/**
* 数据类型
*/
private String type;
/**
* 相别
*/
private String phase;
/**
* 单位
*/
private String unit;
/**
* 数据开始谐波次数
*/
private Integer harmStart;
/**
* 数据结束谐波次数
*/
private Integer harmEnd;
/**
* 数据分类,唯一类别
*/
private String classId;
/**
* 数据统计方法“max”“min”“avg”“cp95”
*/
private String statMethod;
/**
* 系统类别(区分用能/电能)
*/
private String systemType;
/**
* 数据类型(epd、pqd...)
*/
private String dataType;
/**
* 数据是否上送 0:不上送 1:上送
*/
private Integer tranFlag;
/**
* 上送规则 变化:“change”周期:“period”
*/
private String tranRule;
/**
* evt的事件类别 "1"、"2" parm的参数类别 系统参数“sys”运行参数“run”功能参数:“fun” set的定值数据类型 “hex”“number”
*/
private String eventType;
/**
* sts、di的是否存储 1:存储 0:不存储; ctrl的是否加密 1:加密 0:不加密
*/
private Integer storeFlag;
/**
* sts、do的当前值 ctrl的是否需遥控校验 1需要 0不需要
*/
private Integer curSts;
/**
* do的是否可远程控制 1:是 0:否; parm的是否可修改 1:是 0:否; ctrl的是否支持自动控制 1:是 0:否
*/
private Integer ctlSts;
/**
* 设置最大值
*/
private Double maxNum;
/**
* 设置最小值
*/
private Double minNum;
/**
* 参数为enum可设置的所有值序列
*/
private String setValue;
/**
* 参数string可设置字符串的长度上限
*/
private Integer strlen;
/**
* 参数缺省值
*/
private String defaultValue;
/**
* 状态(0:删除 1:正常)
*/
private Integer status;
/**
* 报表数据来源(mysql表名)
*/
private String resourcesId;
/**
* 限值名称
*/
private String limitName;
/**
* 限值表名
*/
private String limitTable;
/**
* 超标判断方式
*/
private String formula;
}

View File

@@ -0,0 +1,47 @@
package com.njcn.roma.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
*
* </p>
*
* @author xy
* @since 2024-08-25
*/
@Getter
@Setter
@TableName("pms_real_data")
public class MonitorRealData {
private static final long serialVersionUID = 1L;
@TableField("id")
private String id;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@TableField("time_Id")
private LocalDateTime timeId;
@MppMultiId
@TableField("line_id")
private String lineId;
@MppMultiId
@TableField("value_type")
private String valueType;
@TableField("pms_content")
private String pmsContent;
}

View File

@@ -0,0 +1,24 @@
//package com.njcn.roma.pojo;
//
//
//import com.baomidou.mybatisplus.annotation.TableField;
//import com.baomidou.mybatisplus.annotation.TableId;
//import com.baomidou.mybatisplus.annotation.TableName;
//import lombok.Data;
//
//import java.io.Serializable;
//
//@Data
//@TableName("pms_history_data")
//public class PmsHistoryDataPO implements Serializable {
// private static final long serialVersionUID = 1L;
//
// @TableField(value = "time")
// private String time;
//
// @TableField(value = "dev_id")
// private String devId;
//
// @TableField(value = "content")
// private String content;
//}

View File

@@ -13,5 +13,7 @@ public class UpSendPojo {
private String deviceId;
private String appId;
private CommandDTO commandDTO;
}

View File

@@ -0,0 +1,13 @@
package com.njcn.roma.pojo.websocket;
import lombok.Data;
@Data
public class SocketMessage {
private Integer type;
private Object body;
}

View File

@@ -0,0 +1,67 @@
package com.njcn.roma.server;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint("/socket")
public class WebSocketServer {
/**
* 全部在线会话 PS: 基于场景考虑 这里使用线程安全的Map存储会话对象。
*/
private static Map<String, Session> onlineSessions = new ConcurrentHashMap<>();
/**
* 当客户端打开连接1.添加会话对象 2.更新在线人数
*/
@OnOpen
public void onOpen(Session session) {
onlineSessions.put(session.getId(), session);
System.out.println("websocket客户端"+session.getId()+"连接");
}
/**
* 当客户端发送消息1.获取它的用户名和消息 2.发送消息给所有人
* <p>
* PS: 这里约定传递的消息为JSON字符串 方便传递更多参数!
*/
@OnMessage
public void onSocketMessage(Session session, String jsonStr) {
}
/**
* 当关闭连接1.移除会话对象 2.更新在线人数
*/
@OnClose
public void onClose(Session session) {
onlineSessions.remove(session.getId());
System.out.println("websocket客户端"+session.getId()+"断开连接");
}
/**
* 当通信发生异常:打印错误日志
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 公共方法:发送信息给所有人
*/
public void sendSocketMessageToAll(String msg) {
onlineSessions.forEach((id, session) -> {
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}

View File

@@ -0,0 +1,13 @@
package com.njcn.roma.service;
import com.github.jeffreyning.mybatisplus.service.IMppService;
import com.njcn.roma.pojo.MonitorRealData;
/**
* roma
*
* @author cdf
* @date 2024/8/25
*/
public interface MonitorRealDataService extends IMppService<MonitorRealData> {
}

View File

@@ -0,0 +1,19 @@
package com.njcn.roma.service.impl;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.roma.mapper.MonitorRealDataMapper;
import com.njcn.roma.pojo.MonitorRealData;
import com.njcn.roma.service.MonitorRealDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* roma
*
* @author cdf
* @date 2024/8/25
*/
@Service
@RequiredArgsConstructor
public class MonitorRealDataServiceImpl extends MppServiceImpl<MonitorRealDataMapper, MonitorRealData> implements MonitorRealDataService {
}

View File

@@ -0,0 +1,124 @@
package com.njcn.roma.utils;
import com.alibaba.fastjson.JSONObject;
import java.lang.reflect.Field;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
public class JsonValueFluctuator {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");
private static final Random random = new Random();
/**
* 模拟给定JSON字符串中数值属性的值上下浮动10%
* @param jsonString JSON字符串
* @return 修改后的JSON字符串
*/
public static JSONObject fluctuateValuesInJson(String jsonString) {
JSONObject jsonObject = JSONObject.parseObject(jsonString);
// 遍历JSONObject的键值对
jsonObject.keySet().forEach(key -> {
Object value = jsonObject.get(key);
if(key.equals("time")){
//ZonedDateTime dateTime = ZonedDateTime.parse(value.toString(), formatter);
// dateTime = dateTime.minusHours(8);
//Instant instant = dateTime.toInstant();
Instant instant = Instant.now();
jsonObject.put(key,instant);
}else {
if(!key.equals("DataTag") && !key.equals("DataType")){
// 假设只有Double类型或可以转换为Double的值需要变动
double numberValue = Double.parseDouble(value.toString());
double fluctuatedValue = fluctuateValue(numberValue);
jsonObject.put(key, fluctuatedValue);
}
}
});
return jsonObject;
}
/**
* 真实环境使用
* @author cdf
* @date 2024/8/21
*/
public static JSONObject realToData(String jsonString) {
JSONObject jsonObject = JSONObject.parseObject(jsonString);
// 遍历JSONObject的键值对
jsonObject.keySet().forEach(key -> {
Object value = jsonObject.get(key);
if(key.equals("time")){
ZonedDateTime dateTime = ZonedDateTime.parse(value.toString(), formatter);
dateTime = dateTime.minusHours(8);
Instant instant = dateTime.toInstant();
jsonObject.put(key,instant);
}else {
if(!key.equals("DataTag") && !key.equals("DataType")) {
// 假设只有Double类型或可以转换为Double的值需要变动
double numberValue = Double.parseDouble(value.toString());
jsonObject.put(key, numberValue);
}
}
});
return jsonObject;
}
/**
* 将对象中所有数字类型的null值字段设置为0对于包装类型
* 注意此方法不处理基本数据类型因为基本数据类型不能是null
*
* @param obj 要处理的对象
*/
public static void setNullNumberFieldsToZero(Object obj) {
if (obj == null) {
return;
}
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
// 确保我们可以访问私有字段
field.setAccessible(true);
try {
// 检查字段是否为数字类型的包装类
if(Integer.class.isAssignableFrom(field.getType())){
if (field.get(obj) == null) {
field.set(obj, 0);
}
} else if (Number.class.isAssignableFrom(field.getType())) {
// 对于包装类型我们可以安全地调用get和set
// 如果字段为null则设置为0
if (field.get(obj) == null) {
field.set(obj, 0.00);
}
}
} catch (IllegalAccessException e) {
// 处理反射访问异常
e.printStackTrace();
}
}
}
/**
* 对给定数值进行上下10%的随机浮动
* @param value 原始数值
* @return 浮动后的数值
*/
private static double fluctuateValue(double value) {
// 随机产生0.9到1.1之间的因子
double factor = 1.0 + (random.nextDouble() * 0.2) - 0.1;
return value * factor;
}
}

View File

@@ -0,0 +1,74 @@
spring:
datasource:
dynamic:
druid:
initial-size: 10
# 初始化大小,最小,最大
min-idle: 20
maxActive: 500
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: true
validation-query: SELECT 1 from dual
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小
poolPreparedStatements: false
maxPoolPreparedStatementPerConnectionSize: -1
filters: stat,wall
filter:
wall:
config:
multi-statement-allow: true
none-base-statement-allow: true
enabled: true
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
allow: #127.0.0.1,192.168.163.1
# IP黑名单 (存在共同时deny优先于allow)
deny: #192.168.1.73
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: njcnpqs
query-timeout: 36000
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://192.168.1.24:13306/pqsinfo_pmscs?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
username: root
password: njcnpqs
driver-class-name: com.mysql.cj.jdbc.Driver
#influxDB内容配置
influx:
url: http://192.168.1.24:8086
user: admin
password: 123456
database: pqsinfo_pms
roma:
acceptIp: 25.36.190.3:19776
sendIp: 25.36.190.7:11443
appId: X_DNZLXT
appKey: IoKU7u47seGwzO4CqGmCaQ==

View File

@@ -0,0 +1,74 @@
spring:
datasource:
dynamic:
druid:
initial-size: 10
# 初始化大小,最小,最大
min-idle: 20
maxActive: 500
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: true
validation-query: SELECT 1 from dual
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小
poolPreparedStatements: false
maxPoolPreparedStatementPerConnectionSize: -1
filters: stat,wall
filter:
wall:
config:
multi-statement-allow: true
none-base-statement-allow: true
enabled: true
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
allow: #127.0.0.1,192.168.163.1
# IP黑名单 (存在共同时deny优先于allow)
deny: #192.168.1.73
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: njcnpqs
query-timeout: 36000
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://25.36.232.37:13306/pmsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
username: root
password: Huawei12#
driver-class-name: com.mysql.cj.jdbc.Driver
influx:
url: http://25.36.232.36:8086
user: admin
password: admin
database: pqsbase_hbcs
mapper-location: com.njcn.influx.imapper
roma:
acceptIp: 25.36.190.3:19776
sendIp: 25.36.190.7:11443
appId: X_DNZLXT
appKey: IoKU7u47seGwzO4CqGmCaQ==

View File

@@ -1,12 +1,33 @@
server:
port: 8790
servlet:
session:
timeout: 1440m
spring:
security:
user:
name: data_njcn
password: dnzl@#002
application:
name: roma
profiles:
active: dev
roma:
acceptIp: 25.36.190.3:19776
sendIp: https://25.36.190.7:11443/iot/1.0/deviceCommands
sendIp: 25.36.190.7:11443
appId: X_DNZLXT
appKey: IoKU7u47seGwzO4CqGmCaQ==
#mybatis配置信息
mybatis-plus:
#别名扫描
type-aliases-package: com.njcn.roma.pojo
global-config:
enable-sql-runner: true
configuration:
#驼峰命名
map-underscore-to-camel-case: true
#配置sql日志输出
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="20 seconds" debug="false">
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProperty scope="context" name="log.projectName" source="spring.application.name" defaultValue="event_msg"/>
<springProperty scope="context" name="logCommonLevel" source="log.commonLevel" defaultValue="info"/>
<springProperty scope="context" name="logHomeDir" source="log.homeDir" defaultValue="E:\logs"/>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="ec"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!--日志输出格式-->
<property name="log.pattern" value="|-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%level} ${log.projectName} -- %t %logger{100}.%M ==> %m%n${Log_EXCEPTION_CONVERSION_WORD:-%ec}}"/>
<property name="log.maxHistory" value="30"/>
<!-- 控制台输出(可选) -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset> <!-- 控制台也建议指定 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!--客户端输出日志-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--系统中常规的debug日志-->
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>
${logHomeDir}/${log.projectName}/debug/debug.log
</file>
<!-- 如果日志级别等于配置级别过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>DEBUG</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责触发滚动 SizeAndTimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>
${logHomeDir}/${log.projectName}/debug/debug.log.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动,且<maxHistory>是6
则只保存最近6个月的文件删除之前的旧文件。注意删除旧文件是那些为了归档而创建的目录也会被删除 -->
<maxHistory>${log.maxHistory:-30}</maxHistory>
<!--重启清理日志文件-->
<!-- <cleanHistoryOnStart>true</cleanHistoryOnStart>-->
<!--每个文件最多100MB保留N天的历史记录但最多20GB-->
<!--<totalSizeCap>20GB</totalSizeCap>-->
<!--日志文件最大的大小-->
<!--<MaxFileSize>${log.maxSize}</MaxFileSize>-->
</rollingPolicy>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--系统中常规的info日志-->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<file>
${logHomeDir}/${log.projectName}/info/info.log
</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${logHomeDir}/${log.projectName}/info/info.log.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>${log.maxHistory:-30}</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>
${log.pattern}
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--系统中常规的error日志-->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>
${logHomeDir}/${log.projectName}/error/error.log
</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${logHomeDir}/${log.projectName}/error/error.log.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>${log.maxHistory:-30}</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>
${log.pattern}
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
<logger name="com.njcn" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG"/>
<appender-ref ref="INFO"/>
<appender-ref ref="ERROR"/>
</logger>
<root level="${logCommonLevel}">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG"/>
<appender-ref ref="INFO"/>
<appender-ref ref="ERROR"/>
</root>
</configuration>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,418 @@
/*!
* Datetimepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datetimepicker {
padding: 4px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
}
.datetimepicker-inline {
width: 220px;
}
.datetimepicker.datetimepicker-rtl {
direction: rtl;
}
.datetimepicker.datetimepicker-rtl table tr td span {
float: right;
}
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
top: 0;
left: 0;
}
[class*=" datetimepicker-dropdown"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #cccccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
[class*=" datetimepicker-dropdown"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
}
[class*=" datetimepicker-dropdown-top"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #cccccc;
border-top-color: rgba(0, 0, 0, 0.2);
border-bottom: 0;
}
[class*=" datetimepicker-dropdown-top"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #ffffff;
border-bottom: 0;
}
.datetimepicker-dropdown-bottom-left:before {
top: -7px;
right: 6px;
}
.datetimepicker-dropdown-bottom-left:after {
top: -6px;
right: 7px;
}
.datetimepicker-dropdown-bottom-right:before {
top: -7px;
left: 6px;
}
.datetimepicker-dropdown-bottom-right:after {
top: -6px;
left: 7px;
}
.datetimepicker-dropdown-top-left:before {
bottom: -7px;
right: 6px;
}
.datetimepicker-dropdown-top-left:after {
bottom: -6px;
right: 7px;
}
.datetimepicker-dropdown-top-right:before {
bottom: -7px;
left: 6px;
}
.datetimepicker-dropdown-top-right:after {
bottom: -6px;
left: 7px;
}
.datetimepicker > div {
display: none;
}
.datetimepicker.minutes div.datetimepicker-minutes {
display: block;
}
.datetimepicker.hours div.datetimepicker-hours {
display: block;
}
.datetimepicker.days div.datetimepicker-days {
display: block;
}
.datetimepicker.months div.datetimepicker-months {
display: block;
}
.datetimepicker.years div.datetimepicker-years {
display: block;
}
.datetimepicker table {
margin: 0;
}
.datetimepicker td,
.datetimepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datetimepicker table tr td,
.table-striped .datetimepicker table tr th {
background-color: transparent;
}
.datetimepicker table tr td.minute:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.hour:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.old,
.datetimepicker table tr td.new {
color: #999999;
}
.datetimepicker table tr td.disabled,
.datetimepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td.today,
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today.disabled,
.datetimepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today:hover:hover,
.datetimepicker table tr td.today.disabled:hover,
.datetimepicker table tr td.today.disabled:hover:hover,
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active,
.datetimepicker table tr td.today.disabled,
.datetimepicker table tr td.today:hover.disabled,
.datetimepicker table tr td.today.disabled.disabled,
.datetimepicker table tr td.today.disabled:hover.disabled,
.datetimepicker table tr td.today[disabled],
.datetimepicker table tr td.today:hover[disabled],
.datetimepicker table tr td.today.disabled[disabled],
.datetimepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active {
background-color: #fbf069;
}
.datetimepicker table tr td.active,
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active.disabled,
.datetimepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active:hover:hover,
.datetimepicker table tr td.active.disabled:hover,
.datetimepicker table tr td.active.disabled:hover:hover,
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active,
.datetimepicker table tr td.active.disabled,
.datetimepicker table tr td.active:hover.disabled,
.datetimepicker table tr td.active.disabled.disabled,
.datetimepicker table tr td.active.disabled:hover.disabled,
.datetimepicker table tr td.active[disabled],
.datetimepicker table tr td.active:hover[disabled],
.datetimepicker table tr td.active.disabled[disabled],
.datetimepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datetimepicker .datetimepicker-hours span {
height: 26px;
line-height: 26px;
}
.datetimepicker .datetimepicker-hours table tr td span.hour_am,
.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
width: 14.6%;
}
.datetimepicker .datetimepicker-hours fieldset legend,
.datetimepicker .datetimepicker-minutes fieldset legend {
margin-bottom: inherit;
line-height: 30px;
}
.datetimepicker .datetimepicker-minutes span {
height: 26px;
line-height: 26px;
}
.datetimepicker table tr td span:hover {
background: #eeeeee;
}
.datetimepicker table tr td span.disabled,
.datetimepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td span.active,
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active.disabled,
.datetimepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active:hover:hover,
.datetimepicker table tr td span.active.disabled:hover,
.datetimepicker table tr td span.active.disabled:hover:hover,
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active,
.datetimepicker table tr td span.active.disabled,
.datetimepicker table tr td span.active:hover.disabled,
.datetimepicker table tr td span.active.disabled.disabled,
.datetimepicker table tr td span.active.disabled:hover.disabled,
.datetimepicker table tr td span.active[disabled],
.datetimepicker table tr td span.active:hover[disabled],
.datetimepicker table tr td span.active.disabled[disabled],
.datetimepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker table tr td span.old {
color: #999999;
}
.datetimepicker th.switch {
width: 145px;
}
.datetimepicker th span.glyphicon {
pointer-events: none;
}
.datetimepicker thead tr:first-child th,
.datetimepicker tfoot th {
cursor: pointer;
}
.datetimepicker thead tr:first-child th:hover,
.datetimepicker tfoot th:hover {
background: #eeeeee;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i,
.input-group.date .input-group-addon span {
cursor: pointer;
width: 14px;
height: 14px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>稳态数据</title>
<link rel="stylesheet" href="./element.css"/>
<script src="./vue.js"></script>
<script src="./echarts.min.js"></script>
</head>
<body>
<template>
<div ref="chart" style="width: 600px; height: 400px;"></div>
</template>
<script type="module">
import * as echarts from './echarts.min.js';
const {createApp,onMounted, ref } = Vue
export default {
setup() {
const chart = ref(null);
onMounted(() => {
const myChart = echarts.init(chart.value);
const option = {
title: {
text: '简单 ECharts 示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
myChart.setOption(option);
});
return { chart };
}
};
</script>
</body>
<style>
table {
width: 100%;
border-collapse: collapse;
}
table caption {
font-size: 2em;
font-weight: bold;
margin: 1em 0;
}
th, td {
border: 1px solid #999;
text-align: center;
padding: 6px 0;
}
table thead tr {
background-color: #008c8c;
color: #fff;
}
table tbody tr:nth-child(odd) {
background-color: #eee;
}
table tbody tr:hover {
background-color: #ccc;
}
table tbody tr td:first-child {
color: #3d34fc;
}
table tfoot tr td {
text-align: right;
padding-right: 20px;
}
</style>
</html>

View File

@@ -6,7 +6,7 @@
<title>谐波次 (%)数表格</title>
<link rel="stylesheet" href="./element.css"/>
<script src="./vue.js"></script>
<script src="./aaa.js" ></script>
<!-- <script src="vue2.0.js" ></script>-->
</head>
<body>
<div id="app">
@@ -25,11 +25,24 @@
<option :value="1">谐波 电压 含有率(%)</option>
</select>
</div>
<div class="div">
<label>装置标识:</label>
<select v-model="devId">
<option value="NJCN230497">NJCN230497</option>
<option value="NJCN230447">NJCN230447</option>
<option value="3206010121">3206010121</option>
</select>
</div>
<button class="el-button" @click="fetchData">读取</button>
<button class="el-button"><a href="harmnic.html">跳转趋势图</a></button>
</div>
<div v-if="data.time" style="float: right">{{data.time.substring(0,4)+'-'+data.time.substring(4,6)+'-'+data.time.substring(6,8)+' '+data.time.substring(9,11)+':'+data.time.substring(11,13)+':'+data.time.substring(13,15)}}</div>
<div style="float: left">装置标识:{{data.customDevId}}</div>
<div v-if="data.time" style="float: right">{{data.time}}</div>
<table v-if="!changeFlag">
<thead>
<tr>
@@ -389,18 +402,9 @@
</div>
<!--<script type="importmap">-->
<!-- {-->
<!-- "imports": {-->
<!-- "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"-->
<!-- }-->
<!-- }-->
<!--</script>-->
<script type="module">
// import {createApp, onMounted, ref} from 'vue'
const {createApp , ref } = Vue
const {createApp, ref} = Vue
createApp({
setup() {
@@ -410,6 +414,7 @@
const toOtherVal = ref(0)
const toOther = (val) => {
console.log(val);
if (toOtherVal.value == 1) {
@@ -419,31 +424,193 @@
}
};
const devId = ref('NJCN230497')
/* const devIdChange = (val) => {
data.value = null;
const fetchData = async () => {
try {
const response = await fetch('/message');
if (!response.ok) {
throw new Error('Network response was not ok');
}
data.value = await response.json();
//data.value = {"HRPhV_H14_phsC":"0.0000","HRPhV_H14_phsB":"0.0000","HRPhV_H17_phsC":"0.0100","HRPhV_H14_phsA":"0.0000","HRPhV_H25_phsB":"0.0080","HRPhV_H25_phsC":"0.0080","HRPhV_H17_phsB":"0.0100","HRPhV_H17_phsA":"0.0100","HRPhV_H25_phsA":"0.0080","HRPhV_H22_phsC":"0.0000","HRPhV_H22_phsB":"0.0000","HRPhV_H22_phsA":"0.0000","DataTag":"0","HRPhV_H20_phsA":"0.0000","HRPhV_H23_phsB":"0.0080","HRPhV_H20_phsB":"0.0000","HRPhV_H23_phsC":"0.0080","PltPhV_phsA":"3.3091","HRPhV_H20_phsC":"0.0000","HRPhV_H15_phsA":"0.0120","HRPhV_H18_phsB":"0.0000","HRPhV_H15_phsB":"0.0120","HRPhV_H18_phsC":"0.0000","HRPhV_H15_phsC":"0.0120","HRPhV_H18_phsA":"0.0000","HRPhV_H23_phsA":"0.0080","HRPhV_H21_phsC":"0.0080","HRPhV_H21_phsB":"0.0080","HRPhV_H24_phsC":"0.0000","HRPhV_H21_phsA":"0.0080","HRPhV_H24_phsB":"0.0000","PltPhV_phsC":"3.2948","HRPhV_H24_phsA":"0.0000","PltPhV_phsB":"3.2992","HRPhV_H19_phsC":"0.0100","HRPhV_H19_phsB":"0.0100","HRPhV_H19_phsA":"0.0100","HRPhV_H16_phsA":"0.0000","HRPhV_H16_phsC":"0.0000","PstPhV_phsC":"3.2942","HRPhV_H16_phsB":"0.0000","PstPhV_phsA":"3.3086","PstPhV_phsB":"3.2987","HRPhV_H13_phsC":"0.0140","time":"20240703T171400Z"}
};*/
console.log(111111111, data.value)
} catch (error) {
console.error('Fetch error:', error);
}
/* const fetchData = async () => {
try {
const response = await fetch('/message');
if (!response.ok) {
throw new Error('Network response was not ok');
}
data.value = await response.json();
//data.value = {"HRPhV_H14_phsC":"0.0000","HRPhV_H14_phsB":"0.0000","HRPhV_H17_phsC":"0.0100","HRPhV_H14_phsA":"0.0000","HRPhV_H25_phsB":"0.0080","HRPhV_H25_phsC":"0.0080","HRPhV_H17_phsB":"0.0100","HRPhV_H17_phsA":"0.0100","HRPhV_H25_phsA":"0.0080","HRPhV_H22_phsC":"0.0000","HRPhV_H22_phsB":"0.0000","HRPhV_H22_phsA":"0.0000","DataTag":"0","HRPhV_H20_phsA":"0.0000","HRPhV_H23_phsB":"0.0080","HRPhV_H20_phsB":"0.0000","HRPhV_H23_phsC":"0.0080","PltPhV_phsA":"3.3091","HRPhV_H20_phsC":"0.0000","HRPhV_H15_phsA":"0.0120","HRPhV_H18_phsB":"0.0000","HRPhV_H15_phsB":"0.0120","HRPhV_H18_phsC":"0.0000","HRPhV_H15_phsC":"0.0120","HRPhV_H18_phsA":"0.0000","HRPhV_H23_phsA":"0.0080","HRPhV_H21_phsC":"0.0080","HRPhV_H21_phsB":"0.0080","HRPhV_H24_phsC":"0.0000","HRPhV_H21_phsA":"0.0080","HRPhV_H24_phsB":"0.0000","PltPhV_phsC":"3.2948","HRPhV_H24_phsA":"0.0000","PltPhV_phsB":"3.2992","HRPhV_H19_phsC":"0.0100","HRPhV_H19_phsB":"0.0100","HRPhV_H19_phsA":"0.0100","HRPhV_H16_phsA":"0.0000","HRPhV_H16_phsC":"0.0000","PstPhV_phsC":"3.2942","HRPhV_H16_phsB":"0.0000","PstPhV_phsA":"3.3086","PstPhV_phsB":"3.2987","HRPhV_H13_phsC":"0.0140","time":"20240703T171400Z"}
console.log(111111111, data.value)
} catch (error) {
console.error('Fetch error:', error);
}
};
fetchData()*/
data.value = {
"time": "20250415T190000Z",
"DataType": "3.000",
"DataTag": "0.000",
"Freq": "49.998",
"FreqDev": "-0.002",
"A_phsA": "1.821",
"A_phsB": "1.884",
"A_phsC": "1.947",
"PhV_phsA": "221.421",
"PhV_phsB": "222.435",
"PhV_phsC": "223.446",
"PPV_phsAB": "379.364",
"PPV_phsBC": "381.109",
"PPV_phsCA": "380.258",
"PhVDev_phsA": "0.924",
"PhVDev_phsB": "1.386",
"PhVDev_phsC": "1.847",
"TotW": "1083.113",
"TotVar": "624.196",
"TotVA": "1251.355",
"TotPF": "0.866",
"SeqV_C1": "219.970",
"SeqV_C2": "0.575",
"SeqV_C0": "0.578",
"ImbNgV": "0.261",
"ImbZroV": "0.263",
"HFundPhV_phsA": "218.972",
"HFundPhV_phsB": "219.973",
"HFundPhV_phsC": "220.974",
"ThdPhV_phsA": "14.999",
"ThdPhV_phsB": "15.001",
"ThdPhV_phsC": "15.002",
"HRPhV_H2_phsA": "3.000",
"HRPhV_H3_phsA": "0.003",
"HRPhV_H4_phsA": "3.000",
"HRPhV_H5_phsA": "0.002",
"HRPhV_H6_phsA": "3.000",
"HRPhV_H7_phsA": "0.001",
"HRPhV_H8_phsA": "3.000",
"HRPhV_H9_phsA": "0.001",
"HRPhV_H10_phsA": "2.999",
"HRPhV_H11_phsA": "0.001",
"HRPhV_H12_phsA": "2.999",
"HRPhV_H13_phsA": "0.001",
"HRPhV_H14_phsA": "3.001",
"HRPhV_H15_phsA": "0.001",
"HRPhV_H16_phsA": "2.999",
"HRPhV_H17_phsA": "0.001",
"HRPhV_H18_phsA": "3.000",
"HRPhV_H19_phsA": "0.001",
"HRPhV_H20_phsA": "2.999",
"HRPhV_H21_phsA": "0.001",
"HRPhV_H22_phsA": "3.000",
"HRPhV_H23_phsA": "0.001",
"HRPhV_H24_phsA": "2.999",
"HRPhV_H25_phsA": "0.001",
"HRPhV_H2_phsB": "3.000",
"HRPhV_H3_phsB": "0.004",
"HRPhV_H4_phsB": "3.001",
"HRPhV_H5_phsB": "0.003",
"HRPhV_H6_phsB": "2.999",
"HRPhV_H7_phsB": "0.002",
"HRPhV_H8_phsB": "3.000",
"HRPhV_H9_phsB": "0.001",
"HRPhV_H10_phsB": "3.000",
"HRPhV_H11_phsB": "0.001",
"HRPhV_H12_phsB": "2.999",
"HRPhV_H13_phsB": "0.002",
"HRPhV_H14_phsB": "3.000",
"HRPhV_H15_phsB": "0.000",
"HRPhV_H16_phsB": "3.001",
"HRPhV_H17_phsB": "0.001",
"HRPhV_H18_phsB": "3.000",
"HRPhV_H19_phsB": "0.001",
"HRPhV_H20_phsB": "3.000",
"HRPhV_H21_phsB": "0.001",
"HRPhV_H22_phsB": "3.000",
"HRPhV_H23_phsB": "0.001",
"HRPhV_H24_phsB": "3.001",
"HRPhV_H25_phsB": "0.001",
"HRPhV_H2_phsC": "3.001",
"HRPhV_H3_phsC": "0.004",
"HRPhV_H4_phsC": "3.001",
"HRPhV_H5_phsC": "0.002",
"HRPhV_H6_phsC": "3.001",
"HRPhV_H7_phsC": "0.002",
"HRPhV_H8_phsC": "3.000",
"HRPhV_H9_phsC": "0.002",
"HRPhV_H10_phsC": "3.000",
"HRPhV_H11_phsC": "0.001",
"HRPhV_H12_phsC": "3.000",
"HRPhV_H13_phsC": "0.000",
"HRPhV_H14_phsC": "3.000",
"HRPhV_H15_phsC": "0.001",
"HRPhV_H16_phsC": "3.001",
"HRPhV_H17_phsC": "0.001",
"HRPhV_H18_phsC": "3.000",
"HRPhV_H19_phsC": "0.000",
"HRPhV_H20_phsC": "3.001",
"HRPhV_H21_phsC": "0.001",
"HRPhV_H22_phsC": "3.000",
"HRPhV_H23_phsC": "0.000",
"HRPhV_H24_phsC": "3.001",
"HRPhV_H25_phsC": "0.000",
"PstPhV_phsA": "0.139",
"PstPhV_phsB": "0.131",
"PstPhV_phsC": "0.153",
"PltPhV_phsA": "0.139",
"PltPhV_phsB": "0.131",
"PltPhV_phsC": "0.153"
}
/**
* 配置 WebSocket
* WebSocket客户端 PSURL开头表示WebSocket协议 中间是域名端口 结尾是服务端映射地址
*/
var webSocket = new WebSocket('ws://localhost:8790/socket');
/**
* 当服务端打开连接
*/
webSocket.onopen = function (event) {
console.log('WebSocket打开连接');
};
fetchData()
/**
* 当服务端发来消息1.广播消息 2.更新在线人数
*/
webSocket.onmessage = function (event) {
console.log('WebSocket收到消息%c' + event.data, 'color:green');
//获取服务端消息
var message = JSON.parse(event.data) || {};
setInterval(fetchData, 10000);
if (devId.value != message.customDevId) {
return false;
}
data.value = message;
}
/**
* 关闭连接
*/
webSocket.onclose = function (event) {
console.log('WebSocket关闭连接');
};
/**
* 通信失败
*/
webSocket.onerror = function (event) {
console.log('WebSocket发生异常');
};
//setInterval(fetchData, 10000);
return {
fetchData,
//fetchData,
data,
changeFlag,
toOther,
toOtherVal
toOtherVal,
devId,
//devIdChange
}
}
}).mount('#app');
@@ -453,6 +620,8 @@
table {
width: 100%;
border-collapse: collapse;
overflow-y: auto; /* 启用竖向滚动 */
}
table caption {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
/**
* Simplified Chinese translation for bootstrap-datetimepicker
* Yuan Cheung <advanimal@gmail.com>
*/
;(function($){
$.fn.datetimepicker.dates['zh-CN'] = {
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
today: "今天",
suffix: [],
meridiem: ["上午", "下午"]
};
}(jQuery));

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,40 @@
package com.njcn.roma;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootTest
import java.time.LocalDateTime;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RomaApplicationTests {
static final Logger log = LoggerFactory.getLogger(RomaApplicationTests.class);
@Autowired
JdbcTemplate jdbcTemplate;
@Test
void contextLoads() {
public void test() throws Exception {
// 1、首先创建数据表
//String ddl = "CREATE TABLE `user` (id INTEGER PRIMARY KEY NOT NULL,name TEXT,create_at TEXT);";
//this.jdbcTemplate.execute(ddl);
// 2、插入一条数据
int ret = this.jdbcTemplate.update("INSERT INTO `pms_history_data` (`time`, `dev_id`, `content`) VALUES (?, ?, ?);", new Object[] {"20240704T152745Z", "NJCN230497", "{\"HRPhV_H14_phsC\":\"0.0000\",\"HRPhV_H14_phsB\":\"0.0000\",\"HRPhV_H14_phsA\":\"0.0000\",\"HRPhV_H2_phsB\":\"0.0100\",\"HRPhV_H2_phsA\":\"0.0100\",\"HRPhV_H2_phsC\":\"0.0100\",\"HRPhV_H15_phsA\":\"0.0120\",\"TotW\":\"19771.1367\",\"HRPhV_H15_phsB\":\"0.0120\",\"HRPhV_H15_phsC\":\"0.0120\",\"FreqDev\":\"0.0000\",\"PPV_phsAB\":\"384.0318\",\"A_phsC\":\"60.86038396125226\",\"TotPF\":\"0.4946\",\"A_phsA\":\"51.428441086632795\",\"A_phsB\":\"62.205840471904295\",\"PPV_phsBC\":\"383.3656\",\"HRPhV_H25_phsB\":\"0.0080\",\"HRPhV_H25_phsC\":\"0.0080\",\"HRPhV_H25_phsA\":\"0.0080\",\"DataTag\":\"0\",\"HRPhV_H20_phsA\":\"0.0000\",\"HRPhV_H20_phsB\":\"0.0000\",\"HRPhV_H20_phsC\":\"0.0000\",\"PPV_phsCA\":\"383.3637\",\"HRPhV_H3_phsB\":\"0.0640\",\"HRPhV_H3_phsC\":\"0.0640\",\"HRPhV_H9_phsC\":\"0.0220\",\"ThdPhV_phsA\":\"0.0913\",\"HRPhV_H9_phsB\":\"0.0220\",\"HRPhV_H9_phsA\":\"0.0220\",\"ThdPhV_phsB\":\"0.0913\",\"ThdPhV_phsC\":\"0.0913\",\"HRPhV_H19_phsC\":\"0.0100\",\"HRPhV_H19_phsB\":\"0.0100\",\"HRPhV_H19_phsA\":\"0.0100\",\"HRPhV_H16_phsA\":\"0.0000\",\"HRPhV_H13_phsA\":\"0.0140\",\"HRPhV_H16_phsC\":\"0.0000\",\"HRPhV_H13_phsB\":\"0.0140\",\"HRPhV_H16_phsB\":\"0.0000\",\"TotVA\":\"39977.2305\",\"HRPhV_H13_phsC\":\"0.0140\",\"HRPhV_H6_phsB\":\"0.0026\",\"HRPhV_H3_phsA\":\"0.0640\",\"HRPhV_H6_phsA\":\"0.0026\",\"HRPhV_H10_phsA\":\"0.0026\",\"HRPhV_H10_phsB\":\"0.0026\",\"HRPhV_H6_phsC\":\"0.0026\",\"HRPhV_H10_phsC\":\"0.0026\",\"ImbNgV\":\"0.0012\",\"TotVar\":\"34745.9492\",\"HRPhV_H7_phsC\":\"0.0280\",\"HRPhV_H7_phsB\":\"0.0280\",\"HRPhV_H22_phsC\":\"0.0000\",\"HRPhV_H22_phsB\":\"0.0000\",\"ImbZroV\":\"0.0012\",\"HRPhV_H22_phsA\":\"0.0000\",\"HRPhV_H7_phsA\":\"0.0280\",\"HRPhV_H8_phsA\":\"0.0026\",\"HRPhV_H23_phsB\":\"0.0080\",\"PhV_phsA\":\"223.11256669838613\",\"HRPhV_H8_phsB\":\"0.0026\",\"HRPhV_H23_phsC\":\"0.0080\",\"HRPhV_H8_phsC\":\"0.0026\",\"customDevId\":\"NJCN230497\",\"PhV_phsB\":\"211.46998705183373\",\"PhV_phsC\":\"214.58076323270137\",\"HRPhV_H23_phsA\":\"0.0080\",\"PstPhV_phsC\":\"3.2942\",\"PstPhV_phsA\":\"3.3086\",\"PstPhV_phsB\":\"3.2987\",\"Freq\":\"50.0000\",\"HRPhV_H11_phsA\":\"0.0180\",\"HRPhV_H11_phsB\":\"0.0180\",\"HRPhV_H17_phsC\":\"0.0100\",\"HRPhV_H11_phsC\":\"0.0180\",\"HRPhV_H17_phsB\":\"0.0100\",\"HRPhV_H17_phsA\":\"0.0100\",\"SeqV_C2\":\"0.0715\",\"HRPhV_H4_phsB\":\"0.0050\",\"SeqV_C1\":\"60.4601\",\"HRPhV_H4_phsA\":\"0.0050\",\"SeqV_C0\":\"0.0714\",\"PhVDev_phsC\":\"0.0119\",\"HRPhV_H5_phsA\":\"0.0400\",\"HRPhV_H5_phsB\":\"0.0400\",\"HRPhV_H5_phsC\":\"0.0400\",\"PhVDev_phsB\":\"0.0119\",\"HRPhV_H12_phsC\":\"0.0010\",\"PltPhV_phsA\":\"0.0000\",\"PhVDev_phsA\":\"0.0119\",\"HRPhV_H12_phsB\":\"0.0010\",\"HRPhV_H4_phsC\":\"0.0050\",\"HRPhV_H18_phsB\":\"0.0000\",\"HRPhV_H18_phsC\":\"0.0000\",\"HRPhV_H12_phsA\":\"0.0010\",\"HRPhV_H18_phsA\":\"0.0000\",\"HFundPhV_phsC\":\"220.8052\",\"HRPhV_H21_phsC\":\"0.0080\",\"HRPhV_H21_phsB\":\"0.0080\",\"HRPhV_H24_phsC\":\"0.0000\",\"HFundPhV_phsA\":\"220.8056\",\"HRPhV_H21_phsA\":\"0.0080\",\"HFundPhV_phsB\":\"220.8055\",\"HRPhV_H24_phsB\":\"0.0000\",\"PltPhV_phsC\":\"0.0000\",\"HRPhV_H24_phsA\":\"0.0000\",\"PltPhV_phsB\":\"0.0000\",\"time\":\"20240704T152745Z\"}"});
log.info("插入数据:{}", ret);
// 3、检索一条数据
//Map<String, Object> user = this.jdbcTemplate.queryForObject("SELECT * FROM `user` WHERE `id` = ?", new ColumnMapRowMapper(), 1L);
//log.info("检索数据:{}", user);
}
}