| | |
| | | import com.ruoyi.common.utils.http.HttpUtils; |
| | | import com.ruoyi.http.service.RealTimeEnergyConsumptionService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collections; |
| | | import java.time.Instant; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * @author :yys |
| | |
| | | @Slf4j |
| | | public class RealTimeEnergyConsumptionServiceImpl implements RealTimeEnergyConsumptionService { |
| | | |
| | | private static final long REMOTE_CACHE_TTL_SECONDS = 10L; |
| | | |
| | | private static final String URL = "https://new.e-elitech.cn/api/data-api"; |
| | | |
| | | private static final String TOKEN_URL = "/elitechAccess/getToken"; |
| | | |
| | | private static final String REAL_TIME_URL = "/elitechAccess/v2/getRealTimeData"; //获取设备实时数据 |
| | | private static final String REAL_TIME_URL = "/elitechAccess/v2/getRealTimeData"; |
| | | |
| | | private static final String REAL_HISTORY_URL = URL + "/elitechAccess/v2/getHistoryData"; |
| | | |
| | | private static final String KET_ID = "75804708"; |
| | | |
| | |
| | | |
| | | private static final String PASS_WORD = "y17775163675"; |
| | | |
| | | private static final String DEVICE_GUID = "90444196515214284663"; |
| | | private static final String REAL_TIME_CACHE_PREFIX = "JCLY:REAL_TIME:"; |
| | | |
| | | private static final String HISTORY_CACHE_PREFIX = "JCLY:HISTORY:"; |
| | | |
| | | /** |
| | | * 根据paramCode提取探头参数 |
| | | * @param paramList 设备参数数组 |
| | | * @param targetCode 目标探头编码 |
| | | * @return 探头参数对象(包含name/value/unit) |
| | | */ |
| | | @Autowired |
| | | private RedisTemplate<String, String> redisTemplate; |
| | | |
| | | private static JSONObject getProbeParam(JSONArray paramList, String targetCode) { |
| | | if (paramList == null) { |
| | | return new JSONObject(); |
| | | } |
| | | for (int i = 0; i < paramList.size(); i++) { |
| | | JSONObject paramObj = paramList.getJSONObject(i); |
| | | if (targetCode.equals(paramObj.getString("paramCode"))) { |
| | | return paramObj; |
| | | } |
| | | } |
| | | return new JSONObject(); // 未匹配到返回空对象,避免空指针 |
| | | return new JSONObject(); |
| | | } |
| | | |
| | | /** |
| | | * 实时获取温湿度,二氧化碳数据 |
| | | */ |
| | | public static void main(String[] args) { |
| | | String realTimeData = getRealTimeData(getToken()); |
| | | Map<String, Object> map = JSON.parseObject(realTimeData, Map.class); |
| | | if(map.get("code").equals(0)){ |
| | | // 1. 解析外层data为JSON数组(接口返回的设备列表) |
| | | JSONArray deviceList = JSON.parseArray(map.get("data").toString()); |
| | | // 2. 遍历设备列表(此处仅取第一个设备,若有多个设备可循环处理) |
| | | if (!deviceList.isEmpty()) { |
| | | JSONObject deviceObj = deviceList.getJSONObject(0); |
| | | // 3. 解析设备内的参数数组(所有paramCode对应的参数) |
| | | JSONArray paramList = deviceObj.getJSONArray("data"); |
| | | public List<Map<String, String>> getHistoryData(String guid, long startTime, long endTime) { |
| | | List<Map<String, String>> resultList = new ArrayList<>(); |
| | | String historyData = requestHistoryData(getToken(), guid, startTime, endTime); |
| | | Map<String, Object> resultMap = JSON.parseObject(historyData, Map.class); |
| | | if (!Integer.valueOf(0).equals(resultMap.get("code"))) { |
| | | return resultList; |
| | | } |
| | | |
| | | // 4. 定义目标探头的paramCode,按需扩展 |
| | | String[] targetCodes = {"0100", "0110", "0120", "0130"}; |
| | | for (String code : targetCodes) { |
| | | // 5. 遍历参数数组,匹配目标paramCode |
| | | for (int i = 0; i < paramList.size(); i++) { |
| | | JSONObject paramObj = paramList.getJSONObject(i); |
| | | String currentCode = paramObj.getString("paramCode"); |
| | | if (code.equals(currentCode)) { |
| | | // 6. 提取核心字段(值、单位、探头名称) |
| | | String paramName = paramObj.getString("paramName"); // 探头1/探头2... |
| | | String value = paramObj.getString("value"); // 数值(345.80/24.90...) |
| | | String unitCode = paramObj.getString("unitCode"); // 单位(Lux/℃/%RH/ppm) |
| | | JSONArray historyList = JSON.parseArray(String.valueOf(resultMap.get("data"))); |
| | | if (historyList == null || historyList.isEmpty()) { |
| | | return resultList; |
| | | } |
| | | |
| | | // 7. 业务处理:打印/赋值/存储等(按需修改) |
| | | System.out.println(paramName + ":" + value + " " + unitCode); |
| | | // 匹配到后直接跳出内层循环,提升效率 |
| | | for (int i = 0; i < historyList.size(); i++) { |
| | | JSONObject historyObj = historyList.getJSONObject(i); |
| | | Map<String, String> historyItem = new HashMap<>(); |
| | | historyItem.put("guid", firstNonBlank( |
| | | historyObj.getString("deviceGuid"), |
| | | historyObj.getString("guid"), |
| | | guid |
| | | )); |
| | | historyItem.put("subUId", stringValue(historyObj.get("subUid"))); |
| | | historyItem.put("monitorTimeStamp", stringValue(historyObj.get("monitorTimeStamp"))); |
| | | historyItem.put("monitorTimeStr", historyObj.getString("monitorTimeStr")); |
| | | historyItem.put("position", historyObj.getString("position")); |
| | | historyItem.put("address", historyObj.getString("address")); |
| | | |
| | | JSONArray paramList = historyObj.getJSONArray("data"); |
| | | if (paramList != null && !paramList.isEmpty()) { |
| | | for (int j = 0; j < paramList.size(); j++) { |
| | | JSONObject paramObj = paramList.getJSONObject(j); |
| | | String paramName = paramObj.getString("paramName"); |
| | | String paramCode = paramObj.getString("paramCode"); |
| | | String value = paramObj.getString("value"); |
| | | String unitCode = paramObj.getString("unitCode"); |
| | | String fullValue = value == null ? null : value + (unitCode == null ? "" : unitCode); |
| | | switch (paramName) { |
| | | case "探头1": |
| | | historyItem.put("light", fullValue); |
| | | break; |
| | | } |
| | | case "探头2": |
| | | historyItem.put("temperature", fullValue); |
| | | break; |
| | | case "探头3": |
| | | historyItem.put("humidity", fullValue); |
| | | break; |
| | | case "探头4": |
| | | historyItem.put("co2", fullValue); |
| | | break; |
| | | default: |
| | | if (paramCode != null) { |
| | | historyItem.put(paramCode, fullValue); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | resultList.add(historyItem); |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | public List<Map<String, String>> getRealData(List<String> guidList) { |
| | | log.info("开始获取实时数据"); |
| | | List<Map<String, String>> listMaps = new ArrayList<>(); |
| | | String realTimeData = getRealTimeData(getToken(), guidList); |
| | | Map<String, Object> map = JSON.parseObject(realTimeData, Map.class); |
| | | if (!Integer.valueOf(0).equals(map.get("code"))) { |
| | | return listMaps; |
| | | } |
| | | |
| | | JSONArray deviceList = JSON.parseArray(String.valueOf(map.get("data"))); |
| | | if (deviceList == null || deviceList.isEmpty()) { |
| | | return listMaps; |
| | | } |
| | | |
| | | String[] targetCodes = {"0100", "0110", "0120", "0130"}; |
| | | for (int deviceIndex = 0; deviceIndex < deviceList.size(); deviceIndex++) { |
| | | JSONObject deviceObj = deviceList.getJSONObject(deviceIndex); |
| | | JSONArray paramList = deviceObj.getJSONArray("data"); |
| | | Map<String, String> deviceData = new HashMap<>(); |
| | | String deviceGuid = firstNonBlank( |
| | | deviceObj.getString("deviceGuid"), |
| | | deviceObj.getString("guid"), |
| | | deviceObj.getString("devGuid"), |
| | | deviceObj.getString("sn") |
| | | ); |
| | | if (deviceGuid != null) { |
| | | deviceData.put("guid", deviceGuid); |
| | | } |
| | | for (String code : targetCodes) { |
| | | JSONObject paramObj = getProbeParam(paramList, code); |
| | | if (paramObj.isEmpty()) { |
| | | continue; |
| | | } |
| | | String paramName = paramObj.getString("paramName"); |
| | | String value = paramObj.getString("value"); |
| | | String unitCode = paramObj.getString("unitCode"); |
| | | log.info("{}: {} {}", paramName, value, unitCode); |
| | | switch (paramName) { |
| | | case "探头1": |
| | | deviceData.put("light", value + unitCode); |
| | | break; |
| | | case "探头2": |
| | | deviceData.put("temperature", value + unitCode); |
| | | break; |
| | | case "探头3": |
| | | deviceData.put("humidity", value + unitCode); |
| | | break; |
| | | case "探头4": |
| | | deviceData.put("co2", value + unitCode); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | listMaps.add(deviceData); |
| | | } |
| | | return listMaps; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | System.out.println(); |
| | | } |
| | | |
| | | public static String getToken(){ |
| | | public String getToken() { |
| | | String cachedToken = sanitizeToken(redisTemplate.opsForValue().get("JCLY_TOKEN:")); |
| | | if (cachedToken != null) { |
| | | return cachedToken; |
| | | } |
| | | Map<String, String> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("userName", USER_NAME); |
| | | param.put("password", PASS_WORD); |
| | | log.info("请求参数:{}", JSON.toJSONString( param)); |
| | | log.info("请求参数:{}", JSON.toJSONString(param)); |
| | | String result = HttpUtils.sendPostJson(URL + TOKEN_URL, JSON.toJSONString(param)); |
| | | log.info("返回结果:{}", result); |
| | | Map<String, Object> map = JSON.parseObject(result, Map.class); |
| | | if (map.get("code").equals(0)) { |
| | | if (Integer.valueOf(0).equals(map.get("code"))) { |
| | | Object token = map.get("data"); |
| | | log.info("token:{}", token); |
| | | redisTemplate.opsForValue().set("JCLY_TOKEN:", token.toString(), 60 * 60 * 24); |
| | | return token.toString(); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static String getRealTimeData(String token){ |
| | | private String sanitizeToken(String token) { |
| | | if (token == null) { |
| | | return null; |
| | | } |
| | | String cleanedToken = token.replace("\0", "").trim(); |
| | | return cleanedToken.isEmpty() ? null : cleanedToken; |
| | | } |
| | | |
| | | private String firstNonBlank(String... values) { |
| | | for (String value : values) { |
| | | if (value != null && !value.trim().isEmpty()) { |
| | | return value; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private String stringValue(Object value) { |
| | | return value == null ? null : String.valueOf(value); |
| | | } |
| | | |
| | | public String getRealTimeData(String token, List<String> guidList) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("deviceGuids", Collections.singletonList(DEVICE_GUID)); |
| | | log.info("请求参数:{}", JSON.toJSONString( param)); |
| | | String result = HttpUtils.sendPostJson(URL + REAL_TIME_URL, JSON.toJSONString(param),token); |
| | | param.put("deviceGuids", guidList); |
| | | log.info("请求参数:{}", JSON.toJSONString(param)); |
| | | String cacheKey = REAL_TIME_CACHE_PREFIX + JSON.toJSONString(param); |
| | | String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); |
| | | if (cachedResult != null) { |
| | | log.info("命中实时数据缓存:{}", cacheKey); |
| | | return cachedResult; |
| | | } |
| | | String result = HttpUtils.sendPostJson(URL + REAL_TIME_URL, JSON.toJSONString(param), token); |
| | | log.info("返回结果:{}", result); |
| | | cacheRemoteResponse(cacheKey, result); |
| | | return result; |
| | | } |
| | | |
| | | public String requestHistoryData(String token, String guid, long startTime, long endTime) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("deviceGuid", guid); |
| | | param.put("startTime", startTime); |
| | | param.put("endTime", endTime); |
| | | log.info("历史数据请求参数:{}", JSON.toJSONString(param)); |
| | | String cacheKey = HISTORY_CACHE_PREFIX + JSON.toJSONString(param); |
| | | String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); |
| | | if (cachedResult != null) { |
| | | log.info("命中历史数据缓存:{}", cacheKey); |
| | | return cachedResult; |
| | | } |
| | | String result = HttpUtils.sendPostJson(REAL_HISTORY_URL, JSON.toJSONString(param), token); |
| | | log.info("历史数据返回结果:{}", result); |
| | | cacheRemoteResponse(cacheKey, result); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private void cacheRemoteResponse(String cacheKey, String result) { |
| | | if (result == null || result.trim().isEmpty()) { |
| | | return; |
| | | } |
| | | redisTemplate.opsForValue().set(cacheKey, result, REMOTE_CACHE_TTL_SECONDS, TimeUnit.SECONDS); |
| | | } |
| | | } |