添加获取扬尘数据定时任务

This commit is contained in:
2024-03-22 16:49:49 +08:00
parent 86815e5fc9
commit aba7040447
9 changed files with 275 additions and 9 deletions

View File

@@ -63,7 +63,11 @@
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>13.2.1</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>

View File

@@ -0,0 +1,27 @@
package cn.lihongjie.coal.emDevice;
import cn.lihongjie.coal.emDevice.client.DustApi;
import feign.Feign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration public class DustClientConfiguration {
@Autowired
DustConfig dustConfig;
@Bean
DustApi dustApi(){
DustApi target = Feign.builder().target(DustApi.class, dustConfig.getUrl());
log.info("dust api url: {}", dustConfig.getUrl());
return target;
}
}

View File

@@ -0,0 +1,20 @@
package cn.lihongjie.coal.emDevice;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@ConfigurationProperties(prefix = "dust")
@Data
public class DustConfig {
private String url;
private Long tokenExpireMinutes;
}

View File

@@ -0,0 +1,72 @@
package cn.lihongjie.coal.emDevice.client;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import java.util.*;
public interface DustApi {
@RequestLine("GET /api/getTokenByAcc?loginName={loginName}&password={password}")
GetTokenResponse getToken(
@Param("loginName") String loginName, @Param("password") String password);
@RequestLine("GET /api/data/getRealtimeData?deviceIds={deviceIds}")
@Headers("token: {token}")
GetRealtimeDataResponse getRealtimeData(@Param("token") String token, @Param("deviceIds") String deviceId);
@RequestLine("GET /api/data/getHistoryData?deviceId={deviceId}&beginTime={beginTime}&endTime={endTime}")
@Headers("token: {token}")
GetRealtimeDataResponse getHistoryData(@Param("token") String token, @Param("deviceId") String deviceId, @Param("beginTime") String beginTime, @Param("endTime") String endTime);
record BaseResponse(String code, String message) {}
record GetTokenData(String token, String expiration) {}
/**
* { "deviceId": "22005373", "status": "offline", "pm25": null, "pm10": null, "noise": null,
* "tem": null, "hum": null, "wp": null, "ws": null, "wd8": null, "wd360": null, "tsp": null,
* "atm": null, "lux": null, "co": null, "so2": null, "no2": null, "o3": null, "r1": 0, "r2": 0,
* "r3": 0, "r4": 0, "r5": 0, "r6": 0, "r7": 0, "r8": 0, "alarmInfos": [] }
*/
record DeviceData(
String deviceId,
String status,
Double pm25,
Double pm10,
Double noise,
Double tem,
Double hum,
Double wp,
Double ws,
Double wd8,
Double wd360,
Double tsp,
Double atm,
Double lux,
Double co,
Double so2,
Double no2,
Double o3,
Integer r1,
Integer r2,
Integer r3,
Integer r4,
Integer r5,
Integer r6,
Integer r7,
Integer r8,
String recordId,
String recordTime,
String strtime
) {}
record GetTokenResponse(String code, String message, GetTokenData data) {}
record GetRealtimeDataResponse(String code, String message, List<DeviceData> data) {}
}

View File

@@ -2,19 +2,27 @@ package cn.lihongjie.coal.emDevice.service;
import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.entity.CommonEntity;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.common.ArchiveUtils;
import cn.lihongjie.coal.dbFunctions.DbFunctionService;
import cn.lihongjie.coal.emDevice.client.DustApi;
import cn.lihongjie.coal.emDevice.dto.CreateEmDeviceDto;
import cn.lihongjie.coal.emDevice.dto.EmDeviceDto;
import cn.lihongjie.coal.emDevice.dto.UpdateEmDeviceDto;
import cn.lihongjie.coal.emDevice.entity.EmDeviceEntity;
import cn.lihongjie.coal.emDevice.mapper.EmDeviceMapper;
import cn.lihongjie.coal.emDevice.repository.EmDeviceRepository;
import cn.lihongjie.coal.emDeviceData.entity.EmDeviceDataEntity;
import cn.lihongjie.coal.emDeviceData.mapper.EmDeviceDataMapper;
import cn.lihongjie.coal.emDeviceData.service.EmDeviceDataService;
import cn.lihongjie.coal.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
@@ -23,6 +31,11 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
@Transactional
@@ -117,4 +130,85 @@ public class EmDeviceService extends BaseService<EmDeviceEntity, EmDeviceReposit
.peek(x -> x.setArchiveStatus("0"))
.forEach(this.repository::save);
}
@Autowired DustApi dustApi;
@Autowired EmDeviceDataService emDeviceDataService;
@Autowired
EmDeviceDataMapper emDeviceDataMapper;
public void queryRealtimeData() {
List<EmDeviceEntity> all = this.repository.findAll();
Map<String, List<EmDeviceEntity>> groupByAccount =
all.stream()
.filter(x -> x.getThirdAccount() != null)
.filter(x -> StringUtils.isNotEmpty(x.getCode()))
.collect(Collectors.groupingBy(d -> d.getThirdAccount().getId()));
Map<String, EmDeviceEntity> codeMap = all.stream().collect(Collectors.toMap(e -> e.getCode(), e -> e));
for (List<EmDeviceEntity> devices : groupByAccount.values()) {
DustApi.GetRealtimeDataResponse realtimeData;
String deviceIds = devices.stream().map(CommonEntity::getCode).collect(Collectors.joining(","));
try {
realtimeData = dustApi.getRealtimeData(devices.get(0).getThirdAccount().getToken() ,deviceIds);
} catch (Exception e) {
log.error("get realtime data error {} ", deviceIds, e);
continue;
}
String code = realtimeData.code();
if (ObjectUtils.notEqual(code, "1000")) {
log.error(
"get realtime data error {} {} {}",
realtimeData.code(),
realtimeData.message(),
realtimeData.data());
continue;
}
List<DustApi.DeviceData> data = realtimeData.data();
if (CollectionUtils.isEmpty(data)) {
log.error(
"get realtime data empty {} {} {}",
realtimeData.code(),
realtimeData.message(),
realtimeData.data());
continue;
}
if (data.size() != devices.size()){
List<String> realTimeCode = data.stream().map(DustApi.DeviceData::deviceId).collect(Collectors.toList());
List<String> deviceCode = devices.stream().map(CommonEntity::getCode).collect(Collectors.toList());
log.info("device code not match {} - {} = {}",deviceCode, realTimeCode, CollectionUtils.removeAll(deviceCode, realTimeCode));
}
List<EmDeviceDataEntity> collect = data.stream().map(x -> {
EmDeviceDataEntity emDeviceData = new EmDeviceDataEntity();
emDeviceData.setDeviceId(codeMap.get(x.deviceId()).getId());
emDeviceData.setOrganizationId(codeMap.get(x.deviceId()).getOrganizationId());
emDeviceData.setTime(LocalDateTime.now());
emDeviceDataMapper.updateEntity(emDeviceData, x);
return emDeviceData;
}).collect(Collectors.toList());
emDeviceDataService.saveAll(collect);
log.info("get realtime data success {} ", deviceIds);
}
}
}

View File

@@ -3,12 +3,16 @@ package cn.lihongjie.coal.emDeviceData.mapper;
import cn.lihongjie.coal.base.mapper.BaseMapper;
import cn.lihongjie.coal.base.mapper.CommonEntityMapper;
import cn.lihongjie.coal.base.mapper.CommonMapper;
import cn.lihongjie.coal.emDevice.client.DustApi;
import cn.lihongjie.coal.emDeviceData.dto.CreateEmDeviceDataDto;
import cn.lihongjie.coal.emDeviceData.dto.EmDeviceDataDto;
import cn.lihongjie.coal.emDeviceData.dto.UpdateEmDeviceDataDto;
import cn.lihongjie.coal.emDeviceData.entity.EmDeviceDataEntity;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.control.DeepClone;
@Mapper(
@@ -20,4 +24,10 @@ public interface EmDeviceDataMapper
EmDeviceDataEntity,
EmDeviceDataDto,
CreateEmDeviceDataDto,
UpdateEmDeviceDataDto> {}
UpdateEmDeviceDataDto> {
@Mappings(
{ @Mapping(target = "status", ignore = true),
@Mapping(target = "deviceId", ignore = true)}
)
void updateEntity(@MappingTarget EmDeviceDataEntity emDeviceData, DustApi.DeviceData x);
}

View File

@@ -4,6 +4,7 @@ import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.dbFunctions.DbFunctionService;
import cn.lihongjie.coal.emDevice.client.DustApi;
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
import cn.lihongjie.coal.organization.service.OrganizationService;
import cn.lihongjie.coal.thirdAccount.dto.CreateThirdAccountDto;
@@ -25,6 +26,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@@ -87,6 +89,8 @@ public class ThirdAccountService extends BaseService<ThirdAccountEntity, ThirdAc
this.repository.findByOrganizationId(organizationEntity.getId()).forEach(this::refresh);
}
@Autowired DustApi dustApi;
private void refresh(ThirdAccountEntity thirdAccountEntity) {
if (thirdAccountEntity.getTokenNextRefreshTime() == null
@@ -97,7 +101,8 @@ public class ThirdAccountService extends BaseService<ThirdAccountEntity, ThirdAc
try {
thirdAccountEntity.setToken(genToken(thirdAccountEntity));
TokenResponse tokenResponse = genToken(thirdAccountEntity);
thirdAccountEntity.setToken(tokenResponse.token);
thirdAccountEntity.setTokenRefreshTime(java.time.LocalDateTime.now());
thirdAccountEntity.setTokenRefreshError(null);
@@ -123,23 +128,39 @@ public class ThirdAccountService extends BaseService<ThirdAccountEntity, ThirdAc
}
}
private String genToken(ThirdAccountEntity thirdAccountEntity) {
private TokenResponse genToken(ThirdAccountEntity thirdAccountEntity) {
switch (thirdAccountEntity.getAccountType()) {
case "1":
return "";
return null;
case "2":
return "";
return null;
case "3":
return "";
return null;
case "4":
return "";
try{
DustApi.GetTokenResponse token = dustApi.getToken(thirdAccountEntity.getUsername(), thirdAccountEntity.getPassword());
return new TokenResponse(
token.data().token(),
LocalDateTime.ofEpochSecond(
Long.parseLong(token.data().expiration()),
0,
java.time.ZoneOffset.ofHours(8)));
}catch (Exception e){
log.error("get token error", e);
throw e;
}
case "5":
return "";
return null;
default:
throw new IllegalArgumentException(
"unknown account type " + thirdAccountEntity.getAccountType());
}
}
record TokenResponse(String token, LocalDateTime expiration) {}
}

View File

@@ -0,0 +1,9 @@
import cn.lihongjie.coal.emDevice.service.EmDeviceService
import org.springframework.context.ApplicationContext
ApplicationContext ioc = ioc
def service = ioc.getBean(EmDeviceService.class)
service.queryRealtimeData()

View File

@@ -0,0 +1,9 @@
import cn.lihongjie.coal.thirdAccount.service.ThirdAccountService
import org.springframework.context.ApplicationContext
ApplicationContext ioc = ioc
def service = ioc.getBean(ThirdAccountService.class)
service.refresh()