重构
This commit is contained in:
@ -70,7 +70,7 @@ spring:
|
|||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 3
|
||||||
# 密码
|
# 密码
|
||||||
password: 12345678
|
password: 12345678
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
@ -92,7 +92,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://172.17.0.13:3306/setri_ems?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://172.17.0.13:3306/setri_ems_new?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: ems
|
username: ems
|
||||||
password: Aa112211!
|
password: Aa112211!
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
@ -188,7 +188,7 @@ xss:
|
|||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
broker.url: tcp://121.5.164.6:1883
|
broker.url: tcp://121.5.164.6:1883
|
||||||
client.id: ems-cloud
|
client.id: ems-cloud-new
|
||||||
username: dmbroker
|
username: dmbroker
|
||||||
password: qwer1234
|
password: qwer1234
|
||||||
connection-timeout: 15
|
connection-timeout: 15
|
||||||
@ -216,7 +216,7 @@ weather:
|
|||||||
influxdb:
|
influxdb:
|
||||||
enabled: true
|
enabled: true
|
||||||
url: http://172.17.0.7:8086/
|
url: http://172.17.0.7:8086/
|
||||||
api-token: B_1HvHbUhubQQhLdI0XtNVw7maWS1aIjVZQ1a3PGD6b-VNg3_JUo_jHgZmjeBKYXnGATNdIqfpl-FAVbJ4UIPg==
|
api-token: l_MUXGYFs15utEaLLLgGUUkHYVA84nweimAyeiHNRIg_FWy3ACcdA85LnxDIBKA8bKxbPp2isTkrqHzrhXtZYw==
|
||||||
write-method: POST
|
write-method: POST
|
||||||
read-method: GET
|
read-method: GET
|
||||||
write-path: /api/v2/write
|
write-path: /api/v2/write
|
||||||
|
|||||||
@ -94,7 +94,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://122.51.194.184:13306/setri_ems?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://122.51.194.184:13306/setri_ems_new?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: ems
|
username: ems
|
||||||
password: 12345678
|
password: 12345678
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
|
|||||||
@ -70,6 +70,18 @@
|
|||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
<!-- InfluxDB 写入成功日志输出 -->
|
||||||
|
<appender name="sys-influxdb" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/sys-influxdb.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${log.path}/sys-influxdb.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<!-- 系统模块日志级别控制 -->
|
<!-- 系统模块日志级别控制 -->
|
||||||
<logger name="com.xzzn" level="info" />
|
<logger name="com.xzzn" level="info" />
|
||||||
@ -90,4 +102,9 @@
|
|||||||
<logger name="sys-user" level="info">
|
<logger name="sys-user" level="info">
|
||||||
<appender-ref ref="sys-user"/>
|
<appender-ref ref="sys-user"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
<!-- InfluxDB 写入成功专用日志 -->
|
||||||
|
<logger name="sys-influxdb" level="info" additivity="false">
|
||||||
|
<appender-ref ref="sys-influxdb"/>
|
||||||
|
</logger>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import java.util.Map;
|
|||||||
public class InfluxPointDataWriter {
|
public class InfluxPointDataWriter {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(InfluxPointDataWriter.class);
|
private static final Logger log = LoggerFactory.getLogger(InfluxPointDataWriter.class);
|
||||||
|
private static final Logger influxWriteSuccessLog = LoggerFactory.getLogger("sys-influxdb");
|
||||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
@Value("${influxdb.enabled:true}")
|
@Value("${influxdb.enabled:true}")
|
||||||
@ -91,6 +92,7 @@ public class InfluxPointDataWriter {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
StringBuilder body = new StringBuilder();
|
StringBuilder body = new StringBuilder();
|
||||||
|
List<String> pointSummaries = new ArrayList<>();
|
||||||
for (PointWritePayload payload : payloads) {
|
for (PointWritePayload payload : payloads) {
|
||||||
if (payload == null || payload.getPointValue() == null) {
|
if (payload == null || payload.getPointValue() == null) {
|
||||||
continue;
|
continue;
|
||||||
@ -103,6 +105,12 @@ public class InfluxPointDataWriter {
|
|||||||
.append(" value=").append(payload.getPointValue().toPlainString())
|
.append(" value=").append(payload.getPointValue().toPlainString())
|
||||||
.append(" ").append(time)
|
.append(" ").append(time)
|
||||||
.append("\n");
|
.append("\n");
|
||||||
|
pointSummaries.add(String.format("siteId=%s, deviceId=%s, pointKey=%s, value=%s, time=%s",
|
||||||
|
safe(payload.getSiteId()),
|
||||||
|
safe(payload.getDeviceId()),
|
||||||
|
safe(payload.getPointKey()),
|
||||||
|
payload.getPointValue(),
|
||||||
|
new Date(time)));
|
||||||
}
|
}
|
||||||
if (body.length() == 0) {
|
if (body.length() == 0) {
|
||||||
return;
|
return;
|
||||||
@ -112,6 +120,8 @@ public class InfluxPointDataWriter {
|
|||||||
log.warn("写入 InfluxDB 失败:v2 写入地址未构建成功,请检查 influxdb.org / influxdb.bucket 配置");
|
log.warn("写入 InfluxDB 失败:v2 写入地址未构建成功,请检查 influxdb.org / influxdb.bucket 配置");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
long startMillis = System.currentTimeMillis();
|
||||||
|
int writeCount = countWriteLines(body);
|
||||||
HttpResult result = executeRequest(methodOrDefault(writeMethod, "POST"), writeUrl, body.toString());
|
HttpResult result = executeRequest(methodOrDefault(writeMethod, "POST"), writeUrl, body.toString());
|
||||||
if (result.code < 200 || result.code >= 300) {
|
if (result.code < 200 || result.code >= 300) {
|
||||||
if (result.code == 404 && isV2WritePath() && isOrgOrBucketMissing(result.body)) {
|
if (result.code == 404 && isV2WritePath() && isOrgOrBucketMissing(result.body)) {
|
||||||
@ -119,6 +129,7 @@ public class InfluxPointDataWriter {
|
|||||||
HttpResult retryResult = executeRequest(methodOrDefault(writeMethod, "POST"), writeUrl, body.toString());
|
HttpResult retryResult = executeRequest(methodOrDefault(writeMethod, "POST"), writeUrl, body.toString());
|
||||||
if (retryResult.code >= 200 && retryResult.code < 300) {
|
if (retryResult.code >= 200 && retryResult.code < 300) {
|
||||||
log.info("InfluxDB org/bucket 自动创建成功,写入已恢复");
|
log.info("InfluxDB org/bucket 自动创建成功,写入已恢复");
|
||||||
|
logWriteSuccess(writeCount, writeUrl, startMillis, pointSummaries);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.warn("InfluxDB 重试写入失败,HTTP状态码: {}, url: {}, body: {}", retryResult.code, writeUrl, safeLog(retryResult.body));
|
log.warn("InfluxDB 重试写入失败,HTTP状态码: {}, url: {}, body: {}", retryResult.code, writeUrl, safeLog(retryResult.body));
|
||||||
@ -126,7 +137,9 @@ public class InfluxPointDataWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.warn("写入 InfluxDB 失败,HTTP状态码: {}, url: {}, body: {}", result.code, writeUrl, safeLog(result.body));
|
log.warn("写入 InfluxDB 失败,HTTP状态码: {}, url: {}, body: {}", result.code, writeUrl, safeLog(result.body));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
logWriteSuccess(writeCount, writeUrl, startMillis, pointSummaries);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("写入 InfluxDB 失败: {}", e.getMessage());
|
log.warn("写入 InfluxDB 失败: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
@ -173,7 +186,8 @@ public class InfluxPointDataWriter {
|
|||||||
startTime.getTime(),
|
startTime.getTime(),
|
||||||
endTime.getTime()
|
endTime.getTime()
|
||||||
);
|
);
|
||||||
values = parseInfluxQlResponse(executeRequestWithResponse(methodOrDefault(readMethod, "GET"), buildQueryUrl(regexQuery)));
|
String regexQueryUrl = buildQueryUrl(regexQuery);
|
||||||
|
values = parseInfluxQlResponse(executeRequestWithResponse(methodOrDefault(readMethod, "GET"), regexQueryUrl));
|
||||||
return values;
|
return values;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("查询 InfluxDB 曲线失败: {}", e.getMessage());
|
log.warn("查询 InfluxDB 曲线失败: {}", e.getMessage());
|
||||||
@ -204,7 +218,8 @@ public class InfluxPointDataWriter {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String queryUrl = buildQueryUrl(influxQl);
|
String queryUrl = buildQueryUrl(influxQl);
|
||||||
return parseInfluxQlResponse(executeRequestWithResponse(methodOrDefault(readMethod, "GET"), queryUrl));
|
List<PointValue> values = parseInfluxQlResponse(executeRequestWithResponse(methodOrDefault(readMethod, "GET"), queryUrl));
|
||||||
|
return values;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("按 pointKey 查询 InfluxDB 曲线失败: {}", e.getMessage());
|
log.warn("按 pointKey 查询 InfluxDB 曲线失败: {}", e.getMessage());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -234,24 +249,9 @@ public class InfluxPointDataWriter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
String queryUrl = buildQueryUrl(influxQl);
|
||||||
List<PointValue> values = parseInfluxQlResponse(
|
List<PointValue> values = parseInfluxQlResponse(
|
||||||
executeRequestWithResponse(methodOrDefault(readMethod, "GET"), buildQueryUrl(influxQl))
|
executeRequestWithResponse(methodOrDefault(readMethod, "GET"), queryUrl)
|
||||||
);
|
|
||||||
if (!values.isEmpty()) {
|
|
||||||
return values.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
String regexQuery = String.format(
|
|
||||||
"SELECT \"value\" FROM \"%s\" WHERE \"site_id\" = '%s' AND \"point_key\" =~ /(?i)^%s$/ " +
|
|
||||||
"AND time >= %dms AND time <= %dms ORDER BY time DESC LIMIT 1",
|
|
||||||
measurement,
|
|
||||||
escapeTagValue(normalizedSiteId),
|
|
||||||
escapeRegex(normalizedPointKey),
|
|
||||||
startTime.getTime(),
|
|
||||||
endTime.getTime()
|
|
||||||
);
|
|
||||||
values = parseInfluxQlResponse(
|
|
||||||
executeRequestWithResponse(methodOrDefault(readMethod, "GET"), buildQueryUrl(regexQuery))
|
|
||||||
);
|
);
|
||||||
return values.isEmpty() ? null : values.get(0);
|
return values.isEmpty() ? null : values.get(0);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -260,6 +260,21 @@ public class InfluxPointDataWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logWriteSuccess(int writeCount, String writeUrl, long startMillis, List<String> pointSummaries) {
|
||||||
|
influxWriteSuccessLog.info("InfluxDB写入成功, count: {}, points: {}, url: {}, costMs: {}",
|
||||||
|
writeCount, pointSummaries, writeUrl, System.currentTimeMillis() - startMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countWriteLines(StringBuilder body) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < body.length(); i++) {
|
||||||
|
if (body.charAt(i) == '\n') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
private String buildWriteUrl() {
|
private String buildWriteUrl() {
|
||||||
if (isV2WritePath()) {
|
if (isV2WritePath()) {
|
||||||
return buildV2WriteUrl();
|
return buildV2WriteUrl();
|
||||||
|
|||||||
@ -2816,15 +2816,16 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
|
|
||||||
private JSONArray parseJsonData(String message) {
|
private JSONArray parseJsonData(String message) {
|
||||||
try {
|
try {
|
||||||
JSONObject object = JSONObject.parseObject(message);
|
Object parsed = JSON.parse(message);
|
||||||
return object.getJSONArray("payload");
|
if (parsed instanceof JSONArray) {
|
||||||
} catch (JSONException e) {
|
return (JSONArray) parsed;
|
||||||
log.info("mqtt message is not a json object: " + e.getMessage());
|
|
||||||
try {
|
|
||||||
return JSONArray.parseArray(message);
|
|
||||||
} catch (Exception arrayException) {
|
|
||||||
log.info("mqtt message is not a json array: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
if (parsed instanceof JSONObject) {
|
||||||
|
return ((JSONObject) parsed).getJSONArray("payload");
|
||||||
|
}
|
||||||
|
log.info("mqtt message root type is unsupported: {}", parsed == null ? "null" : parsed.getClass().getName());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.info("mqtt message parse failed: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -3954,15 +3955,22 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
|
|
||||||
log.info("deviceId:" + deviceId);
|
log.info("deviceId:" + deviceId);
|
||||||
|
|
||||||
|
if (checkJsonDataEmpty(jsonData)) {
|
||||||
|
log.warn("设备告警Data为空,跳过告警处理,siteId: {},deviceId: {}", siteId, deviceId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 存放mqtt原始每个设备最晚一次数据,便于后面点位获取数据
|
// 存放mqtt原始每个设备最晚一次数据,便于后面点位获取数据
|
||||||
redisCache.setCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA_ALARM + siteId + "_" + deviceId, obj);
|
redisCache.setCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA_ALARM + siteId + "_" + deviceId, obj);
|
||||||
// 存放每次同步数据,失效时间(同同步时间)-用于判断是否正常同步数据
|
// 存放每次同步数据,失效时间(同同步时间)-用于判断是否正常同步数据
|
||||||
redisCache.setCacheObject(RedisKeyConstants.SYNC_DATA_ALARM + siteId + "_" + deviceId, obj, 1, TimeUnit.MINUTES);
|
redisCache.setCacheObject(RedisKeyConstants.SYNC_DATA_ALARM + siteId + "_" + deviceId, obj, 1, TimeUnit.MINUTES);
|
||||||
// 处理设备数据,根据不同设备类型进行不同的数据处理
|
// 处理设备数据,根据不同设备类型进行不同的数据处理
|
||||||
String deviceCategory = processingDeviceAlarmData(siteId, deviceId, jsonData, dataUpdateTime);
|
String deviceCategory = processingDeviceAlarmData(siteId, deviceId, jsonData, dataUpdateTime);
|
||||||
if (StringUtils.isEmpty(deviceCategory)) {
|
if (StringUtils.isNotEmpty(deviceCategory)) {
|
||||||
// 处理告警信息
|
// 处理告警信息
|
||||||
alarmDataProcess(siteId, deviceId, jsonData, alarmMatchInfo, deviceCategory);
|
alarmDataProcess(siteId, deviceId, jsonData, alarmMatchInfo, deviceCategory);
|
||||||
|
} else {
|
||||||
|
log.warn("设备告警数据未识别到设备类型,跳过告警处理,siteId: {},deviceId: {}", siteId, deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4097,8 +4105,21 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
|
|
||||||
private void alarmDataProcess(String siteId, String deviceId, String jsonData,
|
private void alarmDataProcess(String siteId, String deviceId, String jsonData,
|
||||||
Map<String, EmsAlarmMatchData> alarmInfoData, String category) {
|
Map<String, EmsAlarmMatchData> alarmInfoData, String category) {
|
||||||
|
if (StringUtils.isEmpty(category)) {
|
||||||
|
log.warn("设备类型为空,跳过告警处理,siteId: {},deviceId: {}", siteId, deviceId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (alarmInfoData == null || alarmInfoData.isEmpty()) {
|
||||||
|
log.warn("告警匹配缓存为空,跳过告警处理,siteId: {},deviceId: {},category: {}", siteId, deviceId, category);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Map<String, Object> obj = JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {
|
Map<String, Object> obj = JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {
|
||||||
});
|
});
|
||||||
|
if (obj == null || obj.isEmpty()) {
|
||||||
|
log.warn("设备告警Data解析结果为空,跳过告警处理,siteId: {},deviceId: {},category: {},data: {}",
|
||||||
|
siteId, deviceId, category, jsonData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String redisKey = RedisKeyConstants.LATEST_ALARM_RECORD + "_" + siteId + "_" + deviceId;
|
String redisKey = RedisKeyConstants.LATEST_ALARM_RECORD + "_" + siteId + "_" + deviceId;
|
||||||
// 获取redis里面的当前有效告警遍历添加到已存在告警key里面
|
// 获取redis里面的当前有效告警遍历添加到已存在告警key里面
|
||||||
@ -4114,12 +4135,8 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
// 结合同步数据,筛选簇需要更新的告警信息
|
// 结合同步数据,筛选簇需要更新的告警信息
|
||||||
List<String> needUpdateKeys = obj.entrySet().stream()
|
List<String> needUpdateKeys = obj.entrySet().stream()
|
||||||
.filter(entry -> {
|
.filter(entry -> {
|
||||||
Object valueObj = entry.getValue();
|
Long value = convertToLong(entry.getValue());
|
||||||
if (valueObj == null) {
|
return value != null && value == 0L && currentAlarmKeys.contains(entry.getKey());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int value = Integer.parseInt(valueObj.toString());
|
|
||||||
return value == 0 && currentAlarmKeys.contains(entry.getKey());
|
|
||||||
})
|
})
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -4129,11 +4146,13 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
if (!needUpdateKeys.isEmpty()) {
|
if (!needUpdateKeys.isEmpty()) {
|
||||||
List<EmsAlarmRecords> records = iEmsAlarmRecordsService.getAllUnfinishedRecords(needUpdateKeys, siteId, deviceId);
|
List<EmsAlarmRecords> records = iEmsAlarmRecordsService.getAllUnfinishedRecords(needUpdateKeys, siteId, deviceId);
|
||||||
// 转为Map便于快速获取
|
// 转为Map便于快速获取
|
||||||
needUpdateMap = records.stream()
|
if (CollectionUtils.isNotEmpty(records)) {
|
||||||
.collect(Collectors.toMap(
|
needUpdateMap = records.stream()
|
||||||
EmsAlarmRecords::getAlarmPoint,
|
.collect(Collectors.toMap(
|
||||||
record -> record
|
EmsAlarmRecords::getAlarmPoint,
|
||||||
));
|
record -> record
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4147,20 +4166,28 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
Long value = (Long) entry.getValue();
|
Long value = convertToLong(entry.getValue());
|
||||||
|
if (value == null) {
|
||||||
|
log.warn("告警值不是有效数字,忽略处理,siteId: {},deviceId: {},point: {},value: {}",
|
||||||
|
siteId, deviceId, key, entry.getValue());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Boolean isCurrentAlarm = currentAlarmKeys.contains(key);
|
Boolean isCurrentAlarm = currentAlarmKeys.contains(key);
|
||||||
String matchRedisKey = siteId + "_" + category + "_" + key;
|
String matchRedisKey = siteId + "_" + category + "_" + key;
|
||||||
// 默认告警值0是正常,1是异常
|
// 默认告警值0是正常,1是异常
|
||||||
Long alarmData = 1L;
|
Long alarmData = 1L;
|
||||||
Object cacheObj = alarmInfoData.get(matchRedisKey);
|
EmsAlarmMatchData matchInfo = alarmInfoData.get(matchRedisKey);
|
||||||
if (cacheObj != null) {
|
if (matchInfo != null) {
|
||||||
EmsAlarmMatchData matchInfo = JSON.toJavaObject(cacheObj, EmsAlarmMatchData.class);
|
|
||||||
alarmData = matchInfo.getAlarmData();
|
alarmData = matchInfo.getAlarmData();
|
||||||
}
|
}
|
||||||
// 处理告警
|
// 处理告警
|
||||||
if (value.equals(alarmData) && !isCurrentAlarm) {
|
if (value.equals(alarmData) && !isCurrentAlarm) {
|
||||||
// 上送值和匹配值相同,新增告警
|
// 上送值和匹配值相同,新增告警
|
||||||
EmsAlarmMatchData matchInfo = JSON.toJavaObject(cacheObj, EmsAlarmMatchData.class);
|
if (matchInfo == null) {
|
||||||
|
log.warn("未找到告警匹配配置,忽略新增告警,siteId: {},deviceId: {},category: {},point: {}",
|
||||||
|
siteId, deviceId, category, key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
EmsAlarmRecords emsAlarmRecord = convertAlarmRecord(siteId, deviceId, matchInfo);
|
EmsAlarmRecords emsAlarmRecord = convertAlarmRecord(siteId, deviceId, matchInfo);
|
||||||
saveOrUpdateList.add(emsAlarmRecord);
|
saveOrUpdateList.add(emsAlarmRecord);
|
||||||
newAddRecordList.add(emsAlarmRecord);
|
newAddRecordList.add(emsAlarmRecord);
|
||||||
@ -4219,6 +4246,24 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Long convertToLong(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
String text = String.valueOf(value);
|
||||||
|
if (StringUtils.isBlank(text)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new BigDecimal(text.trim()).longValue();
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private EmsAlarmRecords convertAlarmRecord(String siteId, String deviceId, EmsAlarmMatchData matchInfo) {
|
private EmsAlarmRecords convertAlarmRecord(String siteId, String deviceId, EmsAlarmMatchData matchInfo) {
|
||||||
EmsAlarmRecords emsAlarmRecords = new EmsAlarmRecords();
|
EmsAlarmRecords emsAlarmRecords = new EmsAlarmRecords();
|
||||||
emsAlarmRecords.setSiteId(siteId);
|
emsAlarmRecords.setSiteId(siteId);
|
||||||
|
|||||||
@ -125,7 +125,10 @@
|
|||||||
t.alarm_content as alarmContent,
|
t.alarm_content as alarmContent,
|
||||||
t.ticket_no as ticketNo,
|
t.ticket_no as ticketNo,
|
||||||
t.id
|
t.id
|
||||||
from ems_alarm_records t INNER JOIN ems_devices_setting t2 on t.site_id = t2.site_id and t.device_id = t2.device_id
|
from ems_alarm_records t
|
||||||
|
INNER JOIN ems_devices_setting t2
|
||||||
|
on t.site_id COLLATE utf8mb4_general_ci = t2.site_id
|
||||||
|
and t.device_id COLLATE utf8mb4_general_ci = t2.device_id
|
||||||
where t.site_id = #{siteId}
|
where t.site_id = #{siteId}
|
||||||
and t.status != 1
|
and t.status != 1
|
||||||
and t.alarm_level in ('C','D')
|
and t.alarm_level in ('C','D')
|
||||||
@ -156,7 +159,9 @@
|
|||||||
t.ticket_no as ticketNo,
|
t.ticket_no as ticketNo,
|
||||||
t.id
|
t.id
|
||||||
from ems_alarm_records t
|
from ems_alarm_records t
|
||||||
LEFT JOIN ems_devices_setting t2 on t.site_id = t2.site_id and t.device_id = t2.device_id
|
LEFT JOIN ems_devices_setting t2
|
||||||
|
on t.site_id = t2.site_id
|
||||||
|
and t.device_id = t2.device_id
|
||||||
where t.site_id = #{siteId}
|
where t.site_id = #{siteId}
|
||||||
<if test="deviceType != null and deviceType != ''">
|
<if test="deviceType != null and deviceType != ''">
|
||||||
AND t.device_type = #{deviceType}
|
AND t.device_type = #{deviceType}
|
||||||
@ -265,4 +270,4 @@
|
|||||||
and device_id = #{deviceId}
|
and device_id = #{deviceId}
|
||||||
and alarm_point is not null
|
and alarm_point is not null
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -288,65 +288,80 @@
|
|||||||
|
|
||||||
<select id="getRevenueDataBySiteId" resultType="com.xzzn.ems.domain.vo.AmmeterRevenueStatisListVo">
|
<select id="getRevenueDataBySiteId" resultType="com.xzzn.ems.domain.vo.AmmeterRevenueStatisListVo">
|
||||||
select
|
select
|
||||||
DATE_FORMAT(t.data_date, '%Y-%m-%d') as dataTime,
|
revenue.dataTime as dataTime,
|
||||||
COALESCE(c.is_workday, CASE WHEN WEEKDAY(t.data_date) < 5 THEN 1 ELSE 0 END) as isWorkday,
|
revenue.isWorkday as isWorkday,
|
||||||
CASE
|
case
|
||||||
WHEN COALESCE(c.is_workday, CASE WHEN WEEKDAY(t.data_date) < 5 THEN 1 ELSE 0 END) = 1 THEN '工作日'
|
when revenue.isWorkday = 1 then '工作日'
|
||||||
ELSE '节假日'
|
else '节假日'
|
||||||
END as dayType,
|
end as dayType,
|
||||||
COALESCE(NULLIF(TRIM(w.weather_desc), ''), '--') as weatherDesc,
|
revenue.weatherDesc as weatherDesc,
|
||||||
ROUND(SUM(IFNULL(t.peak_charge_diff, 0) * IFNULL(pc.peak, 0)), 3) as activePeakPrice,
|
revenue.activePeakPrice as activePeakPrice,
|
||||||
ROUND(SUM(IFNULL(t.peak_discharge_diff, 0) * IFNULL(pc.peak, 0)), 3) as reActivePeakPrice,
|
revenue.reActivePeakPrice as reActivePeakPrice,
|
||||||
ROUND(SUM(IFNULL(t.high_charge_diff, 0) * IFNULL(pc.high, 0)), 3) as activeHighPrice,
|
revenue.activeHighPrice as activeHighPrice,
|
||||||
ROUND(SUM(IFNULL(t.high_discharge_diff, 0) * IFNULL(pc.high, 0)), 3) as reActiveHighPrice,
|
revenue.reActiveHighPrice as reActiveHighPrice,
|
||||||
ROUND(SUM(IFNULL(t.flat_charge_diff, 0) * IFNULL(pc.flat, 0)), 3) as activeFlatPrice,
|
revenue.activeFlatPrice as activeFlatPrice,
|
||||||
ROUND(SUM(IFNULL(t.flat_discharge_diff, 0) * IFNULL(pc.flat, 0)), 3) as reActiveFlatPrice,
|
revenue.reActiveFlatPrice as reActiveFlatPrice,
|
||||||
ROUND(SUM(IFNULL(t.valley_charge_diff, 0) * IFNULL(pc.valley, 0)), 3) as activeValleyPrice,
|
revenue.activeValleyPrice as activeValleyPrice,
|
||||||
ROUND(SUM(IFNULL(t.valley_discharge_diff, 0) * IFNULL(pc.valley, 0)), 3) as reActiveValleyPrice,
|
revenue.reActiveValleyPrice as reActiveValleyPrice,
|
||||||
ROUND(
|
revenue.actualRevenue as actualRevenue
|
||||||
SUM(
|
from (
|
||||||
(IFNULL(t.peak_discharge_diff, 0) - IFNULL(t.peak_charge_diff, 0)) * IFNULL(pc.peak, 0)
|
select
|
||||||
+ (IFNULL(t.high_discharge_diff, 0) - IFNULL(t.high_charge_diff, 0)) * IFNULL(pc.high, 0)
|
DATE_FORMAT(t.data_date, '%Y-%m-%d') as dataTime,
|
||||||
+ (IFNULL(t.flat_discharge_diff, 0) - IFNULL(t.flat_charge_diff, 0)) * IFNULL(pc.flat, 0)
|
COALESCE(c.is_workday, CASE WHEN WEEKDAY(t.data_date) < 5 THEN 1 ELSE 0 END) as isWorkday,
|
||||||
+ (IFNULL(t.valley_discharge_diff, 0) - IFNULL(t.valley_charge_diff, 0)) * IFNULL(pc.valley, 0)
|
COALESCE(NULLIF(TRIM(w.weather_desc), ''), '--') as weatherDesc,
|
||||||
|
ROUND(SUM(IFNULL(t.peak_charge_diff, 0) * IFNULL(pc.peak, 0)), 3) as activePeakPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.peak_discharge_diff, 0) * IFNULL(pc.peak, 0)), 3) as reActivePeakPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.high_charge_diff, 0) * IFNULL(pc.high, 0)), 3) as activeHighPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.high_discharge_diff, 0) * IFNULL(pc.high, 0)), 3) as reActiveHighPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.flat_charge_diff, 0) * IFNULL(pc.flat, 0)), 3) as activeFlatPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.flat_discharge_diff, 0) * IFNULL(pc.flat, 0)), 3) as reActiveFlatPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.valley_charge_diff, 0) * IFNULL(pc.valley, 0)), 3) as activeValleyPrice,
|
||||||
|
ROUND(SUM(IFNULL(t.valley_discharge_diff, 0) * IFNULL(pc.valley, 0)), 3) as reActiveValleyPrice,
|
||||||
|
ROUND(
|
||||||
|
SUM(
|
||||||
|
(IFNULL(t.peak_discharge_diff, 0) - IFNULL(t.peak_charge_diff, 0)) * IFNULL(pc.peak, 0)
|
||||||
|
+ (IFNULL(t.high_discharge_diff, 0) - IFNULL(t.high_charge_diff, 0)) * IFNULL(pc.high, 0)
|
||||||
|
+ (IFNULL(t.flat_discharge_diff, 0) - IFNULL(t.flat_charge_diff, 0)) * IFNULL(pc.flat, 0)
|
||||||
|
+ (IFNULL(t.valley_discharge_diff, 0) - IFNULL(t.valley_charge_diff, 0)) * IFNULL(pc.valley, 0)
|
||||||
|
),
|
||||||
|
3
|
||||||
|
) as actualRevenue
|
||||||
|
from ems_daily_energy_data t
|
||||||
|
left join ems_calendar_day c on c.calendar_date = t.data_date
|
||||||
|
left join ems_site_weather_day w on w.site_id = t.site_id and w.calendar_date = t.data_date
|
||||||
|
left join ems_energy_price_config pc on pc.id = COALESCE(
|
||||||
|
(
|
||||||
|
select p.id
|
||||||
|
from ems_energy_price_config p
|
||||||
|
where p.site_id = t.site_id
|
||||||
|
and STR_TO_DATE(CONCAT(p.year, '-', LPAD(p.month, 2, '0'), '-01'), '%Y-%m-%d') <= DATE_FORMAT(t.data_date, '%Y-%m-01')
|
||||||
|
order by STR_TO_DATE(CONCAT(p.year, '-', LPAD(p.month, 2, '0'), '-01'), '%Y-%m-%d') desc
|
||||||
|
limit 1
|
||||||
),
|
),
|
||||||
3
|
(
|
||||||
) as actualRevenue
|
select p2.id
|
||||||
from ems_daily_energy_data t
|
from ems_energy_price_config p2
|
||||||
left join ems_calendar_day c on c.calendar_date = t.data_date
|
where p2.site_id = t.site_id
|
||||||
left join ems_site_weather_day w on w.site_id = t.site_id and w.calendar_date = t.data_date
|
order by STR_TO_DATE(CONCAT(p2.year, '-', LPAD(p2.month, 2, '0'), '-01'), '%Y-%m-%d') asc
|
||||||
left join ems_energy_price_config pc on pc.id = COALESCE(
|
limit 1
|
||||||
(
|
)
|
||||||
select p.id
|
|
||||||
from ems_energy_price_config p
|
|
||||||
where p.site_id = t.site_id
|
|
||||||
and STR_TO_DATE(CONCAT(p.year, '-', LPAD(p.month, 2, '0'), '-01'), '%Y-%m-%d') <= DATE_FORMAT(t.data_date, '%Y-%m-01')
|
|
||||||
order by STR_TO_DATE(CONCAT(p.year, '-', LPAD(p.month, 2, '0'), '-01'), '%Y-%m-%d') desc
|
|
||||||
limit 1
|
|
||||||
),
|
|
||||||
(
|
|
||||||
select p2.id
|
|
||||||
from ems_energy_price_config p2
|
|
||||||
where p2.site_id = t.site_id
|
|
||||||
order by STR_TO_DATE(CONCAT(p2.year, '-', LPAD(p2.month, 2, '0'), '-01'), '%Y-%m-%d') asc
|
|
||||||
limit 1
|
|
||||||
)
|
)
|
||||||
)
|
where 1=1
|
||||||
where 1=1
|
and t.data_hour is not null
|
||||||
and t.data_hour is not null
|
<if test="siteId != null">
|
||||||
<if test="siteId != null">
|
and t.site_id = #{siteId}
|
||||||
and t.site_id = #{siteId}
|
</if>
|
||||||
</if>
|
<if test="startTime != null">
|
||||||
<if test="startTime != null">
|
and t.data_date >= #{startTime}
|
||||||
and t.data_date >= #{startTime}
|
</if>
|
||||||
</if>
|
<if test="endTime != null">
|
||||||
<if test="endTime != null">
|
and t.data_date <= #{endTime}
|
||||||
and t.data_date <= #{endTime}
|
</if>
|
||||||
</if>
|
group by t.data_date,
|
||||||
group by t.data_date,
|
COALESCE(c.is_workday, CASE WHEN WEEKDAY(t.data_date) < 5 THEN 1 ELSE 0 END),
|
||||||
COALESCE(c.is_workday, CASE WHEN WEEKDAY(t.data_date) < 5 THEN 1 ELSE 0 END),
|
COALESCE(NULLIF(TRIM(w.weather_desc), ''), '--')
|
||||||
COALESCE(NULLIF(TRIM(w.weather_desc), ''), '--')
|
) revenue
|
||||||
order by t.data_date asc
|
order by revenue.dataTime asc
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user