package com.zhgd.xmgl.task; import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSONObject; import com.zhgd.xmgl.modules.doublecarbon.entity.PhotovoltaicPowerCurrentData; import com.zhgd.xmgl.modules.doublecarbon.entity.PhotovoltaicPowerDev; import com.zhgd.xmgl.modules.doublecarbon.entity.dto.Oauth2TokenDTO; import com.zhgd.xmgl.modules.doublecarbon.service.PhotovoltaicPowerCurrentDataService; import com.zhgd.xmgl.modules.doublecarbon.service.PhotovoltaicPowerDevService; import com.zhgd.xmgl.util.Base64; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.SchedulerLock; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * @author 邱平毅 * @ClassName PhotovoltaicPowerTask * @date 2023/1/3 * @Version 1.0 */ @Slf4j @Component public class PhotovoltaicPowerTask { private final String token; PhotovoltaicPowerTask(@Value("${koyoe.clientId}") String clientId, @Value("${koyoe.secret}") String secret) { this.token = Base64.encodeBase64((clientId + ":" + secret).getBytes(StandardCharsets.UTF_8)); } @Value("${koyoe.get-token}") private String getToken; @Value("${koyoe.nowData}") private String nowDataUrl; private Oauth2TokenDTO oauth2TokenDTO; @Resource private PhotovoltaicPowerDevService photovoltaicPowerDevService; @Resource private PhotovoltaicPowerCurrentDataService photovoltaicPowerCurrentDataService; @Resource private RestTemplate restTemplate; /** * 接收第三方厂家数据,获取最新光伏发电设备发电量 */ @SchedulerLock(name = "photovoltaicPowerNowData", lockAtMostFor = 1000 * 60 * 5, lockAtLeastFor = 1000 * 60 * 3) @Scheduled(cron = "0 0/5 * * * ?") public void nowData() { // 光伏发电设备列表 List photovoltaicPowerDevList = photovoltaicPowerDevService.list(); if (photovoltaicPowerDevList == null) { return; } // token刷新 if (oauth2TokenDTO == null || oauth2TokenDTO.getExpiresDate().before(new Date())) { setOauth2Token(); } // 设备id对应总发电量 Map devIdSumMap = photovoltaicPowerCurrentDataService.devSumGeneratingCapacity(); List dataList = new LinkedList<>(); photovoltaicPowerDevList.forEach(dev -> { // 循环查询光伏发电设备的最后一条数据 HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setBearerAuth(oauth2TokenDTO.getAccessToken()); HttpEntity requestEntity = new HttpEntity<>(requestHeaders); ResponseEntity responseEntity; try { responseEntity = restTemplate.exchange(String.format(nowDataUrl, dev.getDevSn()), HttpMethod.GET, requestEntity, JSONObject.class); } catch (Exception e) { e.printStackTrace(); log.error(e.toString()); return; } JSONObject body = responseEntity.getBody(); // 判断请求接口是否正确 if (responseEntity.getStatusCodeValue() != HttpStatus.OK.value() || body == null) { log.error("光伏发电,查找最新一条数据异常!设备sn为:{},响应体为:{}", dev.getDevSn(), responseEntity); return; } // 最后一条数据 JSONObject nowData = body.getJSONObject("nowData"); if (nowData != null) { Float sum = nowData.getFloat("pvTotalOutputPwer"); // 避免恶意数据导致发电值为负值 Long devId = dev.getId(); float generatingCapacity = sum - devIdSumMap.getOrDefault(devId, 0F); if (generatingCapacity > 0) { dataList.add(new PhotovoltaicPowerCurrentData(devId, generatingCapacity)); } } }); if (CollUtil.isNotEmpty(dataList)) { photovoltaicPowerCurrentDataService.saveBatch(dataList); } } private void setOauth2Token() { HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.set("Authorization", "Basic " + token); HttpEntity httpEntity = new HttpEntity<>(requestHeaders); JSONObject jsonObject = restTemplate.postForObject(getToken, httpEntity, JSONObject.class); if (jsonObject != null) { oauth2TokenDTO = new Oauth2TokenDTO(jsonObject.getString("access_token"), jsonObject.getString("scope"), jsonObject.getString("token_type")).setExpiresIn(jsonObject.getInteger("expires_in")); } else { throw new RuntimeException("setOauth2Token#getToken返回体为空!"); } } }