|
@@ -0,0 +1,399 @@
|
|
|
+/*
|
|
|
+ * 文 件 名: Acrel3000Template
|
|
|
+ * 版 权: 华设设计集团股份有限公司
|
|
|
+ * 描 述: <描述>
|
|
|
+ * 修 改 人: lvwenbin
|
|
|
+ * 修改时间: 2025/7/19
|
|
|
+ * 跟踪单号: <跟踪单号>
|
|
|
+ * 修改单号: <修改单号>
|
|
|
+ * 修改内容: <修改内容>
|
|
|
+ */
|
|
|
+package com.ruoyi.ems.core;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.alibaba.fastjson.support.retrofit.Retrofit2ConverterFactory;
|
|
|
+import com.huashe.common.exception.Assert;
|
|
|
+import com.huashe.common.utils.DateUtils;
|
|
|
+import com.ruoyi.common.core.utils.SpringUtils;
|
|
|
+import com.ruoyi.common.redis.service.RedisService;
|
|
|
+import com.ruoyi.ems.config.AcrelConfig;
|
|
|
+import com.ruoyi.ems.model.acrel.AlarmEventLog;
|
|
|
+import com.ruoyi.ems.model.acrel.Circuit;
|
|
|
+import com.ruoyi.ems.model.acrel.ConsumeReport;
|
|
|
+import com.ruoyi.ems.model.acrel.MeterKeyValue;
|
|
|
+import com.ruoyi.ems.model.acrel.MeterUse;
|
|
|
+import com.ruoyi.ems.model.acrel.Station;
|
|
|
+import com.ruoyi.ems.model.acrel.Token;
|
|
|
+import com.ruoyi.ems.retrofit.Acrel3000Api;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import okhttp3.MediaType;
|
|
|
+import okhttp3.OkHttpClient;
|
|
|
+import okhttp3.RequestBody;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import retrofit2.Call;
|
|
|
+import retrofit2.Response;
|
|
|
+import retrofit2.Retrofit;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 安科瑞3000系列模板类
|
|
|
+ * <功能详细描述>
|
|
|
+ *
|
|
|
+ * @author lvwenbin
|
|
|
+ * @version [版本号, 2025/7/19]
|
|
|
+ * @see [相关类/方法]
|
|
|
+ * @since [产品/模块版本]
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class Acrel3000Template extends BaseApiTemplate {
|
|
|
+ /**
|
|
|
+ * 访问地址
|
|
|
+ */
|
|
|
+ protected String url;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用代理
|
|
|
+ */
|
|
|
+ protected final Acrel3000Api api;
|
|
|
+
|
|
|
+ public Acrel3000Template(String restUrl) {
|
|
|
+ this.url = restUrl;
|
|
|
+
|
|
|
+ OkHttpClient httpClient = getClient();
|
|
|
+ Retrofit retrofit = new Retrofit.Builder().baseUrl(restUrl)
|
|
|
+ .addConverterFactory(Retrofit2ConverterFactory.create()).client(httpClient).build();
|
|
|
+ this.api = retrofit.create(Acrel3000Api.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造调用模板
|
|
|
+ *
|
|
|
+ * @param restUrl 服务地址 (http://ip:port)
|
|
|
+ * @param connectTimeout 连接超时
|
|
|
+ * @param readTimeout 读取超时
|
|
|
+ * @param writeTimeout 写超时
|
|
|
+ */
|
|
|
+ public Acrel3000Template(String restUrl, int connectTimeout, int readTimeout, int writeTimeout) {
|
|
|
+ super.connectTimeout = connectTimeout;
|
|
|
+ super.readTimeout = readTimeout;
|
|
|
+ super.writeTimeout = writeTimeout;
|
|
|
+ this.url = restUrl;
|
|
|
+
|
|
|
+ OkHttpClient httpClient = getClient();
|
|
|
+ Retrofit retrofit = new Retrofit.Builder().baseUrl(restUrl)
|
|
|
+ .addConverterFactory(Retrofit2ConverterFactory.create()).client(httpClient).build();
|
|
|
+ api = retrofit.create(Acrel3000Api.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ public synchronized String getAuthToken() {
|
|
|
+ RedisService redisService = SpringUtils.getBean(RedisService.class);
|
|
|
+ String tokenStr = redisService.getCacheObject("ACREL_AUTH_TOKEN");
|
|
|
+
|
|
|
+ if (StringUtils.isEmpty(tokenStr)) {
|
|
|
+ AcrelConfig config = SpringUtils.getBean(AcrelConfig.class);
|
|
|
+ Token token = getAuthToken(config.getAuthLoginName(), config.getAuthPassword());
|
|
|
+ Assert.notNull(token, -1, "获取权限失败");
|
|
|
+
|
|
|
+ Date expireDate = DateUtils.stringToDate(token.getExpireDate(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+ Date currentDate = new Date();
|
|
|
+ long expireSeconds = (expireDate.getTime() - currentDate.getTime()) / 1000;
|
|
|
+ Assert.isTrue(expireSeconds > 0, -1, "Token已过期或过期时间无效");
|
|
|
+ redisService.setCacheObject("ACREL_AUTH_TOKEN", token.getToken(), expireSeconds, TimeUnit.SECONDS);
|
|
|
+ tokenStr = token.getToken();
|
|
|
+ }
|
|
|
+
|
|
|
+ return tokenStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取权限
|
|
|
+ *
|
|
|
+ * @param loginName 用户名
|
|
|
+ * @param password 密码
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public Token getAuthToken(String loginName, String password) {
|
|
|
+ Token token = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 创建请求体
|
|
|
+ RequestBody loginnameBody = RequestBody.create(MediaType.parse("text/plain"), loginName);
|
|
|
+ RequestBody passwordBody = RequestBody.create(MediaType.parse("text/plain"), password);
|
|
|
+
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getAuthToken(loginnameBody, passwordBody);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getAuthToken response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ String dataStr = resJson.getString("data");
|
|
|
+ token = JSONObject.parseObject(dataStr, Token.class);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getAuthToken fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return token;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取站点列表
|
|
|
+ *
|
|
|
+ * @param coacCountNo 企业编号(和站点区域分组id不能同时存在)
|
|
|
+ * @param subGroupId 站点区域分组编号(和企业编号不能同时存在)
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public List<Station> getStationTreeList(String coacCountNo, String subGroupId) {
|
|
|
+ List<Station> stations = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 动态构建参数字段
|
|
|
+ Map<String, RequestBody> fields = new HashMap<>();
|
|
|
+ fields.put("type", RequestBody.create(MediaType.parse("text/plain"), "0"));
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(coacCountNo)) {
|
|
|
+ fields.put("fCoaccountno", RequestBody.create(MediaType.parse("text/plain"), coacCountNo));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(subGroupId)) {
|
|
|
+ fields.put("fSubgroupid", RequestBody.create(MediaType.parse("text/plain"), subGroupId));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getStationTreeList(getAuthToken(), fields);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getStationTreeList response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ JSONObject dataJson = resJson.getJSONObject("data");
|
|
|
+ int num = dataJson.getInteger("num");
|
|
|
+
|
|
|
+ if (num > 0) {
|
|
|
+ String list = dataJson.getString("list");
|
|
|
+ stations = JSONObject.parseArray(list, Station.class);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ stations = new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getStationTreeList fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return stations;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取仪表列表
|
|
|
+ *
|
|
|
+ * @param subId 站点ID
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public List<MeterUse> getMeterUseInfoList(String subId) {
|
|
|
+ List<MeterUse> list = new ArrayList<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ int pageNo = 1;
|
|
|
+ int pageSize = 20;
|
|
|
+ int english = 0;
|
|
|
+ boolean isLastPage;
|
|
|
+
|
|
|
+ do {
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getMeterUseInfoList(getAuthToken(), subId, pageNo, pageSize, english);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getMeterUseInfoList response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ JSONObject dataJson = resJson.getJSONObject("data");
|
|
|
+ isLastPage = dataJson.getBoolean("isLastPage");
|
|
|
+ String listStr = dataJson.getString("list");
|
|
|
+ list.addAll(JSONObject.parseArray(listStr, MeterUse.class));
|
|
|
+
|
|
|
+ pageNo++;
|
|
|
+ }
|
|
|
+ while (!isLastPage);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getMeterUseInfoList fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取回路列表
|
|
|
+ *
|
|
|
+ * @param subId 站点ID
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public List<Circuit> getCircuitInfoTree(String subId) {
|
|
|
+ List<Circuit> circuitList = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getCircuitInfoTree(getAuthToken(), subId);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getCircuitInfoTree response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ String dataStr = resJson.getString("data");
|
|
|
+ circuitList = JSONObject.parseArray(dataStr, Circuit.class);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getCircuitInfoTree fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return circuitList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取实时数据
|
|
|
+ *
|
|
|
+ * @param subId 站点ID
|
|
|
+ * @param meterCode 设备ID
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public List<MeterKeyValue> getMeterParamValueByKey(String subId, String meterCode) {
|
|
|
+ List<MeterKeyValue> meterKvList = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getMeterParamValueByKey(getAuthToken(), subId, meterCode);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getMeterParamValueByKey response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ JSONObject dataJson = resJson.getJSONObject("data");
|
|
|
+ Assert.notNull(dataJson, -1, "data is null!");
|
|
|
+
|
|
|
+ String resultStr = dataJson.getString("result");
|
|
|
+ meterKvList = JSONObject.parseArray(resultStr, MeterKeyValue.class);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getMeterParamValueByKey fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return meterKvList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 用能集抄
|
|
|
+ *
|
|
|
+ * @param circuitIds 回路ID集合
|
|
|
+ * @param type 类型 min:分, hour: 时, day: 日, mon: 月
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public ConsumeReport getNewConsumeReport(String circuitIds, String type, String startTime, String endTime,
|
|
|
+ String interval, String paramCode) {
|
|
|
+ ConsumeReport consumeReport = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 动态构建参数字段
|
|
|
+ Map<String, RequestBody> fields = new HashMap<>();
|
|
|
+ fields.put("fCircuitids", RequestBody.create(MediaType.parse("text/plain"), circuitIds));
|
|
|
+ fields.put("type", RequestBody.create(MediaType.parse("text/plain"), type));
|
|
|
+ fields.put("startTime", RequestBody.create(MediaType.parse("text/plain"), startTime));
|
|
|
+ fields.put("endTime", RequestBody.create(MediaType.parse("text/plain"), endTime));
|
|
|
+ fields.put("interval", RequestBody.create(MediaType.parse("text/plain"), interval));
|
|
|
+ fields.put("paramCode", RequestBody.create(MediaType.parse("text/plain"), paramCode));
|
|
|
+
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getNewConsumeReport(getAuthToken(), fields);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getNewConsumeReport response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ String dataStr = resJson.getString("data");
|
|
|
+ consumeReport = JSONObject.parseObject(dataStr, ConsumeReport.class);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getNewConsumeReport fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return consumeReport;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取报警事件列表
|
|
|
+ * @param subId 站点ID
|
|
|
+ * @param startTime 开始时间
|
|
|
+ * @param endTime 结束时间
|
|
|
+ * @return 响应
|
|
|
+ */
|
|
|
+ public List<AlarmEventLog> getAlarmEventLogList(String subId, String startTime, String endTime) {
|
|
|
+ List<AlarmEventLog> list = new ArrayList<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ int pageNo = 1;
|
|
|
+ int pageSize = 20;
|
|
|
+ boolean isLastPage;
|
|
|
+
|
|
|
+ do {
|
|
|
+ // 动态构建参数字段
|
|
|
+ Map<String, RequestBody> fields = new HashMap<>();
|
|
|
+
|
|
|
+ if (null != subId) {
|
|
|
+ fields.put("subId", RequestBody.create(MediaType.parse("text/plain"), subId));
|
|
|
+ }
|
|
|
+
|
|
|
+ fields.put("startTime", RequestBody.create(MediaType.parse("text/plain"), startTime));
|
|
|
+ fields.put("endTime", RequestBody.create(MediaType.parse("text/plain"), endTime));
|
|
|
+ fields.put("pageNo", RequestBody.create(MediaType.parse("text/plain"), String.valueOf(pageNo)));
|
|
|
+ fields.put("pageSize", RequestBody.create(MediaType.parse("text/plain"), String.valueOf(pageSize)));
|
|
|
+
|
|
|
+ // 执行调用
|
|
|
+ Call<String> call = api.getAlarmEventLogList(getAuthToken(), fields);
|
|
|
+ Response<String> response = call.execute();
|
|
|
+ log.debug("getAlarmEventLogList response:{}", response);
|
|
|
+
|
|
|
+ JSONObject resJson = JSONObject.parseObject(response.body());
|
|
|
+ Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
|
|
|
+ resJson.getString("msg"));
|
|
|
+
|
|
|
+ JSONObject dataJson = resJson.getJSONObject("data");
|
|
|
+ Assert.notNull(dataJson, -1, "data is null!");
|
|
|
+ JSONObject alarmJson = dataJson.getJSONObject("alarmEventLogList");
|
|
|
+
|
|
|
+ isLastPage = alarmJson.getBoolean("isLastPage");
|
|
|
+ String listStr = alarmJson.getString("list");
|
|
|
+ List<AlarmEventLog> tmp = JSONObject.parseArray(listStr, AlarmEventLog.class);
|
|
|
+
|
|
|
+ list.addAll(tmp);
|
|
|
+
|
|
|
+ fields.clear();
|
|
|
+ pageNo++;
|
|
|
+ }
|
|
|
+ while (!isLastPage);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("getAlarmEventLogList fail!", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+}
|