Commit 5489e1511ac4651408847b76a8d68ec9e2ec73af

Authored by 杨鸣坤
1 parent 1d30326a

feat: 添加安徽安景瑞和安徽华猫设备数据同步服务

  1 +package com.iot.scheduler.service;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.alibaba.fastjson.TypeReference;
  7 +import com.iot.scheduler.model.DeviceToken;
  8 +import com.iot.scheduler.model.QxDeviceInfo;
  9 +import com.iot.scheduler.model.QxDeviceInfoDetail;
  10 +import jakarta.annotation.Resource;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +import org.apache.http.Consts;
  14 +import org.apache.http.HttpEntity;
  15 +import org.apache.http.client.methods.CloseableHttpResponse;
  16 +import org.apache.http.client.methods.HttpGet;
  17 +import org.apache.http.client.methods.HttpPost;
  18 +import org.apache.http.entity.ContentType;
  19 +import org.apache.http.entity.StringEntity;
  20 +import org.apache.http.impl.client.CloseableHttpClient;
  21 +import org.apache.http.impl.client.HttpClients;
  22 +import org.apache.http.message.BasicHeader;
  23 +import org.apache.http.util.EntityUtils;
  24 +import org.springframework.beans.factory.annotation.Value;
  25 +import org.springframework.data.redis.core.RedisTemplate;
  26 +import org.springframework.stereotype.Service;
  27 +import org.springframework.util.CollectionUtils;
  28 +import org.springframework.util.LinkedMultiValueMap;
  29 +import org.springframework.util.MultiValueMap;
  30 +import org.springframework.web.util.UriComponentsBuilder;
  31 +
  32 +import java.io.ByteArrayOutputStream;
  33 +import java.io.IOException;
  34 +import java.io.InputStream;
  35 +import java.text.SimpleDateFormat;
  36 +import java.util.*;
  37 +import java.util.concurrent.TimeUnit;
  38 +
  39 +/**
  40 + * 安徽安景瑞应用数据同步
  41 + */
  42 +@Slf4j
  43 +@Service
  44 +public class AhajrDevicePullService {
  45 +
  46 + @Value("${ahajr.iot.organizeId:}")
  47 + private String iotOrganizeId;
  48 + @Value("${ahajr.iot.profileId}")
  49 + private String iotProfileId;
  50 + @Value("${ahajr.iot.deviceProfileId}")
  51 + private String iotDeviceProfileId;
  52 + @Value("${ahajr.iot.userName:}")
  53 + private String iotUserName;
  54 + @Value("${ahajr.iot.password:}")
  55 + private String iotPassword;
  56 + @Value("${ahajr.iot.tokenUrl}")
  57 + private String iotTokenUrl;
  58 + @Value("${ahajr.iot.infoUrl}")
  59 + private String iotDeviceInfoUrl;
  60 + @Value("${ahajr.iot.detailUrl}")
  61 + private String iotDeviceDetailUrl;
  62 +
  63 + @Value("${device.token.url}")
  64 + private String deviceTokenUrl;
  65 + @Value("${device.token.userName}")
  66 + private String deviceUserName;
  67 + @Value("${device.token.password}")
  68 + private String devicePassword;
  69 + @Value("${device.info.url}")
  70 + private String deviceInfoUrl;
  71 + @Value("${device.detail.url}")
  72 + private String deviceDetailUrl;
  73 +
  74 + @Resource
  75 + private RedisTemplate<String, String> redisTemplate;
  76 +
  77 + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  78 +
  79 + public void pullDeviceAndPushToIot() {
  80 + String deviceResult = getDeviceInfo();
  81 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  82 + });
  83 +
  84 + JSONArray deviceInfoList = (JSONArray) deviceInfos.get("data");
  85 + List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>();
  86 + List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>();
  87 + Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>();
  88 + for (Object o : deviceInfoList) {
  89 + JSONObject deviceInfoJson = (JSONObject) o;
  90 + QxDeviceInfo qxDeviceInfo = new QxDeviceInfo();
  91 + qxDeviceInfo.setDeviceType("DIRECT_CONNECTION");
  92 + qxDeviceInfo.setTransportType("DEFAULT");
  93 + qxDeviceInfo.setOrganizationId(iotOrganizeId);
  94 + qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId);
  95 + qxDeviceInfo.setProfileId(iotProfileId);
  96 +// //项目状态(1:在线,2:离线,3:报警)
  97 +// Integer projectState = deviceInfoJson.getInteger("projectState");
  98 +// if (projectState != null) {
  99 +// qxDeviceInfo.setDescription(String.valueOf(projectState));
  100 +// }
  101 +
  102 + //项目类型
  103 + qxDeviceInfo.setLabel("生产设备");
  104 + //设备名称
  105 + String deviceName = deviceInfoJson.getString("deviceName");
  106 +
  107 + qxDeviceInfo.setName(deviceName);
  108 + qxDeviceInfo.setBrand(deviceName);
  109 + //序列号
  110 + String dtuSn = deviceInfoJson.getString("dtuSn");
  111 + qxDeviceInfo.setSn(dtuSn);
  112 + //高速/中速
  113 + boolean highSpeed = deviceName.contains("高速");
  114 + if (highSpeed) {
  115 + qxDeviceInfo.setDescription("高速机");
  116 + } else {
  117 + qxDeviceInfo.setDescription("中速机");
  118 + }
  119 +
  120 + DeviceToken deviceToken = new DeviceToken();
  121 + deviceToken.setCredentialsType("ACCESS_TOKEN");
  122 + deviceToken.setCredentialsId(dtuSn);
  123 + deviceToken.setCredentialsValue(dtuSn);
  124 + qxDeviceInfo.setDeviceToken(deviceToken);
  125 + qxDeviceInfos.add(qxDeviceInfo);
  126 + //有序列号直接获取灯信息
  127 + if (StringUtils.isNotBlank(dtuSn)) {
  128 + String deviceInfoDetails = getDeviceInfoDetail(dtuSn);
  129 + if (StringUtils.isBlank(deviceInfoDetails)) {
  130 + continue;
  131 + }
  132 +
  133 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetails, new TypeReference<>() {
  134 + });
  135 +
  136 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  137 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  138 + continue;
  139 + }
  140 +
  141 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  142 + //灯详情数据
  143 + //序列号
  144 + String dtuSnDetail = deviceInfoDetailJson.getString("dtuSn");
  145 + //开始时间
  146 + String startTime = deviceInfoDetailJson.getString("startTime");
  147 + QxDeviceInfoDetail qxDeviceInfoDetail = new QxDeviceInfoDetail();
  148 + qxDeviceInfoDetail.setAlarm(false);
  149 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  150 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  151 + switch (lampState) {
  152 + case 0:
  153 + qxDeviceInfoDetail.setStatus("OFF");
  154 + break;
  155 + case 1:
  156 + qxDeviceInfoDetail.setStatus("ERROR");
  157 + qxDeviceInfoDetail.setAlarm(true);
  158 + break;
  159 + case 2:
  160 + qxDeviceInfoDetail.setStatus("STAND");
  161 + break;
  162 + case 3:
  163 + qxDeviceInfoDetail.setStatus("RUN");
  164 + //先从缓存里面拿token信息
  165 + break;
  166 + default:
  167 + continue;
  168 + }
  169 +
  170 + if (StringUtils.isNotBlank(startTime)) {
  171 + try {
  172 + qxDeviceInfoDetail.setStartTime(dateFormat.parse(startTime));
  173 + } catch (Exception e) {
  174 + log.error("时间格式出错");
  175 + qxDeviceInfoDetail.setStartTime(new Date());
  176 + }
  177 + } else {
  178 + qxDeviceInfoDetail.setStartTime(new Date());
  179 + }
  180 +
  181 + qxDeviceInfoDetail.setDtuSn(dtuSn);
  182 + qxDeviceInfoDetailMap.put(dtuSn, qxDeviceInfoDetail);
  183 + qxAddDeviceInfoDetails.add(qxDeviceInfoDetail);
  184 + }
  185 + }
  186 +
  187 + //将数据同步到IOT平台
  188 + Map<String, String> qxParam = new HashMap<>(2);
  189 + qxParam.put("username", iotUserName);
  190 + qxParam.put("password", iotPassword);
  191 +
  192 + HttpPost qxHttpPost = new HttpPost(iotTokenUrl);
  193 + String qxResult = sendPost(qxHttpPost, JSON.toJSONString(qxParam));
  194 + if (StringUtils.isBlank(qxResult)) {
  195 + return;
  196 + }
  197 + Map<String, Object> qxRes = JSON.parseObject(qxResult, new TypeReference<Map<String, Object>>() {
  198 + });
  199 +
  200 + String qxAccessToken = (String) qxRes.get("token");
  201 + if (StringUtils.isBlank(qxAccessToken)) {
  202 + return;
  203 + }
  204 +
  205 + BasicHeader qxAuthorization = new BasicHeader("X-Authorization", "Bearer " + qxAccessToken);
  206 + if (!CollectionUtils.isEmpty(qxDeviceInfos)) {
  207 + HttpPost qxDeviceInfoPost = new HttpPost(iotDeviceInfoUrl);
  208 + qxDeviceInfoPost.addHeader(qxAuthorization);
  209 + for (QxDeviceInfo qxDeviceInfo : qxDeviceInfos) {
  210 + // todo
  211 + String syncDeviceInfo = sendPost(qxDeviceInfoPost, JSON.toJSONString(qxDeviceInfo));
  212 + //log.info("同步设备信息 syncDeviceInfo:{}", syncDeviceInfo);
  213 + }
  214 + }
  215 +
  216 + if (!CollectionUtils.isEmpty(qxAddDeviceInfoDetails)) {
  217 + for (QxDeviceInfoDetail qxDeviceInfoDetail : qxAddDeviceInfoDetails) {
  218 + String qxDeviceInfoDetailUrlStr = iotDeviceDetailUrl + qxDeviceInfoDetail.getDtuSn() + "/telemetry";
  219 + HttpPost qxDeviceInfoDetailPost = new HttpPost(qxDeviceInfoDetailUrlStr);
  220 + qxDeviceInfoDetailPost.addHeader(qxAuthorization);
  221 + String syncDeviceInfoDetail = sendPost(qxDeviceInfoDetailPost, JSON.toJSONString(qxDeviceInfoDetail));
  222 + }
  223 + }
  224 + }
  225 +
  226 + public String getDeviceInfoDetail(String dtuSn) {
  227 + String accessToken = getAccessToken();
  228 + Map<String, String> dtuSnOb = new HashMap<>(1);
  229 + dtuSnOb.put("dtuSn", dtuSn);
  230 + Map<String, String> headerMap = new HashMap<>(1);
  231 + headerMap.put("Authorization", "Bearer " + accessToken);
  232 + String deviceInfoDetail = sendRequestGet(deviceDetailUrl, dtuSnOb, headerMap);
  233 + if (StringUtils.isBlank(deviceInfoDetail)) {
  234 + return null;
  235 + }
  236 +
  237 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetail,
  238 + new TypeReference<>() {
  239 + });
  240 + Integer deviceInfoDetailCode = (Integer) deviceInfoDetailMap.get("code");
  241 + if (deviceInfoDetailCode != 200) {
  242 + return null;
  243 + }
  244 +
  245 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  246 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  247 + return null;
  248 + }
  249 +
  250 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  251 + //灯详情数据
  252 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  253 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  254 + if (lampState == null) {
  255 + return null;
  256 + }
  257 +
  258 + return deviceInfoDetail;
  259 + }
  260 +
  261 + public String getDeviceInfo() {
  262 + String accessToken = getAccessToken();
  263 + // 初始化headerMap并设置Authorization
  264 + Map<String, String> headerMap = new HashMap<>(1);
  265 + headerMap.put("Authorization", "Bearer " + accessToken);
  266 +
  267 + Map<String, String> paramsMap = new HashMap<>();
  268 + paramsMap.put("groupName", "安徽安景瑞医疗防护用品科技有限公司");
  269 +
  270 + // 第一次请求设备信息
  271 + String deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  272 +
  273 + // 检查设备信息是否为空
  274 + if (StringUtils.isBlank(deviceResult)) {
  275 + return null;
  276 + }
  277 +
  278 + // 解析设备信息
  279 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  280 + });
  281 + Integer deviceInfoCode = (Integer) deviceInfos.get("code");
  282 +
  283 + // 如果code不为200,可能是accessToken失效,重新获取token并重试
  284 + if (deviceInfoCode != 200) {
  285 + accessToken = getAccessToken();
  286 + if (StringUtils.isEmpty(accessToken)) {
  287 + return null;
  288 + }
  289 +
  290 + // 更新headerMap中的Authorization
  291 + headerMap.put("Authorization", "Bearer " + accessToken);
  292 +
  293 + // 第二次请求设备信息
  294 + deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  295 + if (StringUtils.isBlank(deviceResult)) {
  296 + return null;
  297 + }
  298 +
  299 + // 重新解析设备信息
  300 + deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  301 + });
  302 + deviceInfoCode = (Integer) deviceInfos.get("code");
  303 +
  304 + // 如果第二次请求仍然失败,返回错误信息
  305 + if (deviceInfoCode != 200) {
  306 + return null;
  307 + }
  308 + }
  309 +
  310 + // 返回成功的设备信息
  311 + return deviceResult;
  312 + }
  313 +
  314 + private String getAccessToken() {
  315 + String accessToken = "";
  316 + String redisKey = "device_token";
  317 + if (StringUtils.isNotBlank(redisTemplate.opsForValue().get(redisKey)) && redisTemplate.getExpire(redisKey) > 0) {
  318 + return redisTemplate.opsForValue().get(redisKey);
  319 + }
  320 +
  321 + Map<String, String> param = new HashMap<>(2);
  322 + param.put("username", deviceUserName);
  323 + param.put("password", devicePassword);
  324 + HttpPost httpPost = new HttpPost(deviceTokenUrl);
  325 + String result = sendPost(httpPost, JSON.toJSONString(param));
  326 + if (StringUtils.isBlank(result)) {
  327 + return accessToken;
  328 + }
  329 +
  330 + Map<String, Object> res = JSON.parseObject(result, new TypeReference<>() {
  331 + });
  332 +
  333 + Integer code = (Integer) res.get("code");
  334 + if (code == 200) {
  335 + JSONObject data = (JSONObject) res.get("data");
  336 + accessToken = (String) data.get("token");
  337 + redisTemplate.opsForValue().set(redisKey, accessToken, 3600, TimeUnit.SECONDS); // 一小时过期
  338 + }
  339 +
  340 + return accessToken;
  341 + }
  342 +
  343 + public static String sendRequestGet(String url, Map<String, String> params, Map<String, String> header) {
  344 + //实例化httpclient
  345 + CloseableHttpClient httpclient = HttpClients.createDefault();
  346 + url = builderUrl(url, params);
  347 + //请求结果
  348 + String content = "";
  349 + //实例化get方法
  350 + HttpGet httpget = new HttpGet(url);
  351 + if (!CollectionUtils.isEmpty(header)) {
  352 + for (Map.Entry<String, String> entry : header.entrySet()) {
  353 + httpget.setHeader(entry.getKey(), entry.getValue());
  354 + }
  355 + }
  356 +
  357 + try (CloseableHttpResponse response = httpclient.execute(httpget)) {
  358 +
  359 + //执行get方法
  360 + if (response.getStatusLine().getStatusCode() == 200) {
  361 + content = EntityUtils.toString(response.getEntity(), "UTF-8");
  362 + }
  363 + } catch (IOException e) {
  364 + log.error("sendRequest---GET Error!", e);
  365 + }
  366 + return content;
  367 + }
  368 +
  369 + private static String builderUrl(String url, Map<String, String> params) {
  370 + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
  371 + if (!CollectionUtils.isEmpty(params)) {
  372 + MultiValueMap<String, String> paramsValue = new LinkedMultiValueMap<>();
  373 + for (Map.Entry<String, String> entry : params.entrySet()) {
  374 + paramsValue.add(entry.getKey(), entry.getValue());
  375 + }
  376 +
  377 + uriBuilder = uriBuilder.queryParams(paramsValue);
  378 + }
  379 +
  380 + return uriBuilder.toUriString();
  381 + }
  382 +
  383 + private String sendPost(HttpPost httpPost, String jsonData) {
  384 + CloseableHttpClient httpClient = HttpClients.createDefault();
  385 + StringEntity entity = new StringEntity(jsonData, ContentType.create("application/json", Consts.UTF_8));
  386 + httpPost.setEntity(entity);
  387 + String result = null;
  388 + try {
  389 + CloseableHttpResponse execute = httpClient.execute(httpPost);
  390 + HttpEntity res = execute.getEntity();
  391 + InputStream is = res.getContent();
  392 + int len;
  393 + byte[] buf = new byte[128];
  394 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  395 + while ((len = is.read(buf)) != -1) {
  396 + byteArrayOutputStream.write(buf, 0, len);
  397 + }
  398 + result = byteArrayOutputStream.toString();
  399 + } catch (IOException e) {
  400 + e.printStackTrace();
  401 + }
  402 + return result;
  403 + }
  404 +}
  1 +package com.iot.scheduler.service;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.alibaba.fastjson.TypeReference;
  7 +import com.iot.scheduler.model.DeviceToken;
  8 +import com.iot.scheduler.model.QxDeviceInfo;
  9 +import com.iot.scheduler.model.QxDeviceInfoDetail;
  10 +import jakarta.annotation.Resource;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +import org.apache.http.Consts;
  14 +import org.apache.http.HttpEntity;
  15 +import org.apache.http.client.methods.CloseableHttpResponse;
  16 +import org.apache.http.client.methods.HttpGet;
  17 +import org.apache.http.client.methods.HttpPost;
  18 +import org.apache.http.entity.ContentType;
  19 +import org.apache.http.entity.StringEntity;
  20 +import org.apache.http.impl.client.CloseableHttpClient;
  21 +import org.apache.http.impl.client.HttpClients;
  22 +import org.apache.http.message.BasicHeader;
  23 +import org.apache.http.util.EntityUtils;
  24 +import org.springframework.beans.factory.annotation.Value;
  25 +import org.springframework.data.redis.core.RedisTemplate;
  26 +import org.springframework.stereotype.Service;
  27 +import org.springframework.util.CollectionUtils;
  28 +import org.springframework.util.LinkedMultiValueMap;
  29 +import org.springframework.util.MultiValueMap;
  30 +import org.springframework.web.util.UriComponentsBuilder;
  31 +
  32 +import java.io.ByteArrayOutputStream;
  33 +import java.io.IOException;
  34 +import java.io.InputStream;
  35 +import java.text.SimpleDateFormat;
  36 +import java.util.*;
  37 +import java.util.concurrent.TimeUnit;
  38 +
  39 +/**
  40 + * 安徽华猫应用数据同步
  41 + */
  42 +@Slf4j
  43 +@Service
  44 +public class AhhmDevicePullService {
  45 +
  46 + @Value("${ahhm.iot.organizeId:}")
  47 + private String iotOrganizeId;
  48 + @Value("${ahhm.iot.profileId}")
  49 + private String iotProfileId;
  50 + @Value("${ahhm.iot.deviceProfileId}")
  51 + private String iotDeviceProfileId;
  52 + @Value("${ahhm.iot.userName:}")
  53 + private String iotUserName;
  54 + @Value("${ahhm.iot.password:}")
  55 + private String iotPassword;
  56 + @Value("${ahhm.iot.tokenUrl}")
  57 + private String iotTokenUrl;
  58 + @Value("${ahhm.iot.infoUrl}")
  59 + private String iotDeviceInfoUrl;
  60 + @Value("${ahhm.iot.detailUrl}")
  61 + private String iotDeviceDetailUrl;
  62 +
  63 + @Value("${device.token.url}")
  64 + private String deviceTokenUrl;
  65 + @Value("${device.token.userName}")
  66 + private String deviceUserName;
  67 + @Value("${device.token.password}")
  68 + private String devicePassword;
  69 + @Value("${device.info.url}")
  70 + private String deviceInfoUrl;
  71 + @Value("${device.detail.url}")
  72 + private String deviceDetailUrl;
  73 +
  74 + @Resource
  75 + private RedisTemplate<String, String> redisTemplate;
  76 +
  77 + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  78 +
  79 + public void pullDeviceAndPushToIot() {
  80 + String deviceResult = getDeviceInfo();
  81 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  82 + });
  83 +
  84 + JSONArray deviceInfoList = (JSONArray) deviceInfos.get("data");
  85 + List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>();
  86 + List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>();
  87 + Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>();
  88 + for (Object o : deviceInfoList) {
  89 + JSONObject deviceInfoJson = (JSONObject) o;
  90 + QxDeviceInfo qxDeviceInfo = new QxDeviceInfo();
  91 + qxDeviceInfo.setDeviceType("DIRECT_CONNECTION");
  92 + qxDeviceInfo.setTransportType("DEFAULT");
  93 + qxDeviceInfo.setOrganizationId(iotOrganizeId);
  94 + qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId);
  95 + qxDeviceInfo.setProfileId(iotProfileId);
  96 +// //项目状态(1:在线,2:离线,3:报警)
  97 +// Integer projectState = deviceInfoJson.getInteger("projectState");
  98 +// if (projectState != null) {
  99 +// qxDeviceInfo.setDescription(String.valueOf(projectState));
  100 +// }
  101 +
  102 + //项目类型
  103 + qxDeviceInfo.setLabel("生产设备");
  104 + //设备名称
  105 + String deviceName = deviceInfoJson.getString("deviceName");
  106 +
  107 + qxDeviceInfo.setName(deviceName);
  108 + qxDeviceInfo.setBrand(deviceName);
  109 + //序列号
  110 + String dtuSn = deviceInfoJson.getString("dtuSn");
  111 + qxDeviceInfo.setSn(dtuSn);
  112 + //高速/中速
  113 + boolean highSpeed = deviceName.contains("高速");
  114 + if (highSpeed) {
  115 + qxDeviceInfo.setDescription("高速机");
  116 + } else {
  117 + qxDeviceInfo.setDescription("中速机");
  118 + }
  119 +
  120 + DeviceToken deviceToken = new DeviceToken();
  121 + deviceToken.setCredentialsType("ACCESS_TOKEN");
  122 + deviceToken.setCredentialsId(dtuSn);
  123 + deviceToken.setCredentialsValue(dtuSn);
  124 + qxDeviceInfo.setDeviceToken(deviceToken);
  125 + qxDeviceInfos.add(qxDeviceInfo);
  126 + //有序列号直接获取灯信息
  127 + if (StringUtils.isNotBlank(dtuSn)) {
  128 + String deviceInfoDetails = getDeviceInfoDetail(dtuSn);
  129 + if (StringUtils.isBlank(deviceInfoDetails)) {
  130 + continue;
  131 + }
  132 +
  133 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetails, new TypeReference<>() {
  134 + });
  135 +
  136 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  137 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  138 + continue;
  139 + }
  140 +
  141 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  142 + //灯详情数据
  143 + //序列号
  144 + String dtuSnDetail = deviceInfoDetailJson.getString("dtuSn");
  145 + //开始时间
  146 + String startTime = deviceInfoDetailJson.getString("startTime");
  147 + QxDeviceInfoDetail qxDeviceInfoDetail = new QxDeviceInfoDetail();
  148 + qxDeviceInfoDetail.setAlarm(false);
  149 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  150 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  151 + switch (lampState) {
  152 + case 0:
  153 + qxDeviceInfoDetail.setStatus("OFF");
  154 + break;
  155 + case 1:
  156 + qxDeviceInfoDetail.setStatus("ERROR");
  157 + qxDeviceInfoDetail.setAlarm(true);
  158 + break;
  159 + case 2:
  160 + qxDeviceInfoDetail.setStatus("STAND");
  161 + break;
  162 + case 3:
  163 + qxDeviceInfoDetail.setStatus("RUN");
  164 + //先从缓存里面拿token信息
  165 + break;
  166 + default:
  167 + continue;
  168 + }
  169 +
  170 + if (StringUtils.isNotBlank(startTime)) {
  171 + try {
  172 + qxDeviceInfoDetail.setStartTime(dateFormat.parse(startTime));
  173 + } catch (Exception e) {
  174 + log.error("时间格式出错");
  175 + qxDeviceInfoDetail.setStartTime(new Date());
  176 + }
  177 + } else {
  178 + qxDeviceInfoDetail.setStartTime(new Date());
  179 + }
  180 +
  181 + qxDeviceInfoDetail.setDtuSn(dtuSn);
  182 + qxDeviceInfoDetailMap.put(dtuSn, qxDeviceInfoDetail);
  183 + qxAddDeviceInfoDetails.add(qxDeviceInfoDetail);
  184 + }
  185 + }
  186 +
  187 + //将数据同步到IOT平台
  188 + Map<String, String> qxParam = new HashMap<>(2);
  189 + qxParam.put("username", iotUserName);
  190 + qxParam.put("password", iotPassword);
  191 +
  192 + HttpPost qxHttpPost = new HttpPost(iotTokenUrl);
  193 + String qxResult = sendPost(qxHttpPost, JSON.toJSONString(qxParam));
  194 + if (StringUtils.isBlank(qxResult)) {
  195 + return;
  196 + }
  197 + Map<String, Object> qxRes = JSON.parseObject(qxResult, new TypeReference<Map<String, Object>>() {
  198 + });
  199 +
  200 + String qxAccessToken = (String) qxRes.get("token");
  201 + if (StringUtils.isBlank(qxAccessToken)) {
  202 + return;
  203 + }
  204 +
  205 + BasicHeader qxAuthorization = new BasicHeader("X-Authorization", "Bearer " + qxAccessToken);
  206 + if (!CollectionUtils.isEmpty(qxDeviceInfos)) {
  207 + HttpPost qxDeviceInfoPost = new HttpPost(iotDeviceInfoUrl);
  208 + qxDeviceInfoPost.addHeader(qxAuthorization);
  209 + for (QxDeviceInfo qxDeviceInfo : qxDeviceInfos) {
  210 + // todo
  211 + String syncDeviceInfo = sendPost(qxDeviceInfoPost, JSON.toJSONString(qxDeviceInfo));
  212 + //log.info("同步设备信息 syncDeviceInfo:{}", syncDeviceInfo);
  213 + }
  214 + }
  215 +
  216 + if (!CollectionUtils.isEmpty(qxAddDeviceInfoDetails)) {
  217 + for (QxDeviceInfoDetail qxDeviceInfoDetail : qxAddDeviceInfoDetails) {
  218 + String qxDeviceInfoDetailUrlStr = iotDeviceDetailUrl + qxDeviceInfoDetail.getDtuSn() + "/telemetry";
  219 + HttpPost qxDeviceInfoDetailPost = new HttpPost(qxDeviceInfoDetailUrlStr);
  220 + qxDeviceInfoDetailPost.addHeader(qxAuthorization);
  221 + String syncDeviceInfoDetail = sendPost(qxDeviceInfoDetailPost, JSON.toJSONString(qxDeviceInfoDetail));
  222 + }
  223 + }
  224 + }
  225 +
  226 + public String getDeviceInfoDetail(String dtuSn) {
  227 + String accessToken = getAccessToken();
  228 + Map<String, String> dtuSnOb = new HashMap<>(1);
  229 + dtuSnOb.put("dtuSn", dtuSn);
  230 + Map<String, String> headerMap = new HashMap<>(1);
  231 + headerMap.put("Authorization", "Bearer " + accessToken);
  232 + String deviceInfoDetail = sendRequestGet(deviceDetailUrl, dtuSnOb, headerMap);
  233 + if (StringUtils.isBlank(deviceInfoDetail)) {
  234 + return null;
  235 + }
  236 +
  237 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetail,
  238 + new TypeReference<>() {
  239 + });
  240 + Integer deviceInfoDetailCode = (Integer) deviceInfoDetailMap.get("code");
  241 + if (deviceInfoDetailCode != 200) {
  242 + return null;
  243 + }
  244 +
  245 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  246 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  247 + return null;
  248 + }
  249 +
  250 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  251 + //灯详情数据
  252 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  253 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  254 + if (lampState == null) {
  255 + return null;
  256 + }
  257 +
  258 + return deviceInfoDetail;
  259 + }
  260 +
  261 + public String getDeviceInfo() {
  262 + String accessToken = getAccessToken();
  263 + // 初始化headerMap并设置Authorization
  264 + Map<String, String> headerMap = new HashMap<>(1);
  265 + headerMap.put("Authorization", "Bearer " + accessToken);
  266 +
  267 + Map<String, String> paramsMap = new HashMap<>();
  268 + paramsMap.put("groupName", "安徽华猫软包装有限公司");
  269 +
  270 + // 第一次请求设备信息
  271 + String deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  272 +
  273 + // 检查设备信息是否为空
  274 + if (StringUtils.isBlank(deviceResult)) {
  275 + return null;
  276 + }
  277 +
  278 + // 解析设备信息
  279 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  280 + });
  281 + Integer deviceInfoCode = (Integer) deviceInfos.get("code");
  282 +
  283 + // 如果code不为200,可能是accessToken失效,重新获取token并重试
  284 + if (deviceInfoCode != 200) {
  285 + accessToken = getAccessToken();
  286 + if (StringUtils.isEmpty(accessToken)) {
  287 + return null;
  288 + }
  289 +
  290 + // 更新headerMap中的Authorization
  291 + headerMap.put("Authorization", "Bearer " + accessToken);
  292 +
  293 + // 第二次请求设备信息
  294 + deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  295 + if (StringUtils.isBlank(deviceResult)) {
  296 + return null;
  297 + }
  298 +
  299 + // 重新解析设备信息
  300 + deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  301 + });
  302 + deviceInfoCode = (Integer) deviceInfos.get("code");
  303 +
  304 + // 如果第二次请求仍然失败,返回错误信息
  305 + if (deviceInfoCode != 200) {
  306 + return null;
  307 + }
  308 + }
  309 +
  310 + // 返回成功的设备信息
  311 + return deviceResult;
  312 + }
  313 +
  314 + private String getAccessToken() {
  315 + String accessToken = "";
  316 + String redisKey = "device_token";
  317 + if (StringUtils.isNotBlank(redisTemplate.opsForValue().get(redisKey)) && redisTemplate.getExpire(redisKey) > 0) {
  318 + return redisTemplate.opsForValue().get(redisKey);
  319 + }
  320 +
  321 + Map<String, String> param = new HashMap<>(2);
  322 + param.put("username", deviceUserName);
  323 + param.put("password", devicePassword);
  324 + HttpPost httpPost = new HttpPost(deviceTokenUrl);
  325 + String result = sendPost(httpPost, JSON.toJSONString(param));
  326 + if (StringUtils.isBlank(result)) {
  327 + return accessToken;
  328 + }
  329 +
  330 + Map<String, Object> res = JSON.parseObject(result, new TypeReference<>() {
  331 + });
  332 +
  333 + Integer code = (Integer) res.get("code");
  334 + if (code == 200) {
  335 + JSONObject data = (JSONObject) res.get("data");
  336 + accessToken = (String) data.get("token");
  337 + redisTemplate.opsForValue().set(redisKey, accessToken, 3600, TimeUnit.SECONDS); // 一小时过期
  338 + }
  339 +
  340 + return accessToken;
  341 + }
  342 +
  343 + public static String sendRequestGet(String url, Map<String, String> params, Map<String, String> header) {
  344 + //实例化httpclient
  345 + CloseableHttpClient httpclient = HttpClients.createDefault();
  346 + url = builderUrl(url, params);
  347 + //请求结果
  348 + String content = "";
  349 + //实例化get方法
  350 + HttpGet httpget = new HttpGet(url);
  351 + if (!CollectionUtils.isEmpty(header)) {
  352 + for (Map.Entry<String, String> entry : header.entrySet()) {
  353 + httpget.setHeader(entry.getKey(), entry.getValue());
  354 + }
  355 + }
  356 +
  357 + try (CloseableHttpResponse response = httpclient.execute(httpget)) {
  358 +
  359 + //执行get方法
  360 + if (response.getStatusLine().getStatusCode() == 200) {
  361 + content = EntityUtils.toString(response.getEntity(), "UTF-8");
  362 + }
  363 + } catch (IOException e) {
  364 + log.error("sendRequest---GET Error!", e);
  365 + }
  366 + return content;
  367 + }
  368 +
  369 + private static String builderUrl(String url, Map<String, String> params) {
  370 + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
  371 + if (!CollectionUtils.isEmpty(params)) {
  372 + MultiValueMap<String, String> paramsValue = new LinkedMultiValueMap<>();
  373 + for (Map.Entry<String, String> entry : params.entrySet()) {
  374 + paramsValue.add(entry.getKey(), entry.getValue());
  375 + }
  376 +
  377 + uriBuilder = uriBuilder.queryParams(paramsValue);
  378 + }
  379 +
  380 + return uriBuilder.toUriString();
  381 + }
  382 +
  383 + private String sendPost(HttpPost httpPost, String jsonData) {
  384 + CloseableHttpClient httpClient = HttpClients.createDefault();
  385 + StringEntity entity = new StringEntity(jsonData, ContentType.create("application/json", Consts.UTF_8));
  386 + httpPost.setEntity(entity);
  387 + String result = null;
  388 + try {
  389 + CloseableHttpResponse execute = httpClient.execute(httpPost);
  390 + HttpEntity res = execute.getEntity();
  391 + InputStream is = res.getContent();
  392 + int len;
  393 + byte[] buf = new byte[128];
  394 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  395 + while ((len = is.read(buf)) != -1) {
  396 + byteArrayOutputStream.write(buf, 0, len);
  397 + }
  398 + result = byteArrayOutputStream.toString();
  399 + } catch (IOException e) {
  400 + e.printStackTrace();
  401 + }
  402 + return result;
  403 + }
  404 +}
  1 +package com.iot.scheduler.service;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.alibaba.fastjson.TypeReference;
  7 +import com.iot.scheduler.model.DeviceToken;
  8 +import com.iot.scheduler.model.QxDeviceInfo;
  9 +import com.iot.scheduler.model.QxDeviceInfoDetail;
  10 +import jakarta.annotation.Resource;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +import org.apache.http.Consts;
  14 +import org.apache.http.HttpEntity;
  15 +import org.apache.http.client.methods.CloseableHttpResponse;
  16 +import org.apache.http.client.methods.HttpGet;
  17 +import org.apache.http.client.methods.HttpPost;
  18 +import org.apache.http.entity.ContentType;
  19 +import org.apache.http.entity.StringEntity;
  20 +import org.apache.http.impl.client.CloseableHttpClient;
  21 +import org.apache.http.impl.client.HttpClients;
  22 +import org.apache.http.message.BasicHeader;
  23 +import org.apache.http.util.EntityUtils;
  24 +import org.springframework.beans.factory.annotation.Value;
  25 +import org.springframework.data.redis.core.RedisTemplate;
  26 +import org.springframework.stereotype.Service;
  27 +import org.springframework.util.CollectionUtils;
  28 +import org.springframework.util.LinkedMultiValueMap;
  29 +import org.springframework.util.MultiValueMap;
  30 +import org.springframework.web.util.UriComponentsBuilder;
  31 +
  32 +import java.io.ByteArrayOutputStream;
  33 +import java.io.IOException;
  34 +import java.io.InputStream;
  35 +import java.text.SimpleDateFormat;
  36 +import java.util.*;
  37 +import java.util.concurrent.TimeUnit;
  38 +
  39 +/**
  40 + * 一诺纸业应用数据同步
  41 + */
  42 +@Slf4j
  43 +@Service
  44 +public class YnzyDevicePullService {
  45 +
  46 + @Value("${ynzy.iot.organizeId:}")
  47 + private String iotOrganizeId;
  48 + @Value("${ynzy.iot.profileId}")
  49 + private String iotProfileId;
  50 + @Value("${ynzy.iot.deviceProfileId}")
  51 + private String iotDeviceProfileId;
  52 + @Value("${ynzy.iot.userName:}")
  53 + private String iotUserName;
  54 + @Value("${ynzy.iot.password:}")
  55 + private String iotPassword;
  56 + @Value("${ynzy.iot.tokenUrl}")
  57 + private String iotTokenUrl;
  58 + @Value("${ynzy.iot.infoUrl}")
  59 + private String iotDeviceInfoUrl;
  60 + @Value("${ynzy.iot.detailUrl}")
  61 + private String iotDeviceDetailUrl;
  62 +
  63 + @Value("${device.token.url}")
  64 + private String deviceTokenUrl;
  65 + @Value("${device.token.userName}")
  66 + private String deviceUserName;
  67 + @Value("${device.token.password}")
  68 + private String devicePassword;
  69 + @Value("${device.info.url}")
  70 + private String deviceInfoUrl;
  71 + @Value("${device.detail.url}")
  72 + private String deviceDetailUrl;
  73 +
  74 + @Resource
  75 + private RedisTemplate<String, String> redisTemplate;
  76 +
  77 + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  78 +
  79 + public void pullDeviceAndPushToIot() {
  80 + String deviceResult = getDeviceInfo();
  81 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  82 + });
  83 +
  84 + JSONArray deviceInfoList = (JSONArray) deviceInfos.get("data");
  85 + List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>();
  86 + List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>();
  87 + Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>();
  88 + for (Object o : deviceInfoList) {
  89 + JSONObject deviceInfoJson = (JSONObject) o;
  90 + QxDeviceInfo qxDeviceInfo = new QxDeviceInfo();
  91 + qxDeviceInfo.setDeviceType("DIRECT_CONNECTION");
  92 + qxDeviceInfo.setTransportType("DEFAULT");
  93 + qxDeviceInfo.setOrganizationId(iotOrganizeId);
  94 + qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId);
  95 + qxDeviceInfo.setProfileId(iotProfileId);
  96 +// //项目状态(1:在线,2:离线,3:报警)
  97 +// Integer projectState = deviceInfoJson.getInteger("projectState");
  98 +// if (projectState != null) {
  99 +// qxDeviceInfo.setDescription(String.valueOf(projectState));
  100 +// }
  101 +
  102 + //项目类型
  103 + qxDeviceInfo.setLabel("生产设备");
  104 + //设备名称
  105 + String deviceName = deviceInfoJson.getString("deviceName");
  106 +
  107 + qxDeviceInfo.setName(deviceName);
  108 + qxDeviceInfo.setBrand(deviceName);
  109 + //序列号
  110 + String dtuSn = deviceInfoJson.getString("dtuSn");
  111 + qxDeviceInfo.setSn(dtuSn);
  112 + //高速/中速
  113 + boolean highSpeed = deviceName.contains("高速");
  114 + if (highSpeed) {
  115 + qxDeviceInfo.setDescription("高速机");
  116 + } else {
  117 + qxDeviceInfo.setDescription("中速机");
  118 + }
  119 +
  120 + DeviceToken deviceToken = new DeviceToken();
  121 + deviceToken.setCredentialsType("ACCESS_TOKEN");
  122 + deviceToken.setCredentialsId(dtuSn);
  123 + deviceToken.setCredentialsValue(dtuSn);
  124 + qxDeviceInfo.setDeviceToken(deviceToken);
  125 + qxDeviceInfos.add(qxDeviceInfo);
  126 + //有序列号直接获取灯信息
  127 + if (StringUtils.isNotBlank(dtuSn)) {
  128 + String deviceInfoDetails = getDeviceInfoDetail(dtuSn);
  129 + if (StringUtils.isBlank(deviceInfoDetails)) {
  130 + continue;
  131 + }
  132 +
  133 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetails, new TypeReference<>() {
  134 + });
  135 +
  136 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  137 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  138 + continue;
  139 + }
  140 +
  141 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  142 + //灯详情数据
  143 + //序列号
  144 + String dtuSnDetail = deviceInfoDetailJson.getString("dtuSn");
  145 + //开始时间
  146 + String startTime = deviceInfoDetailJson.getString("startTime");
  147 + QxDeviceInfoDetail qxDeviceInfoDetail = new QxDeviceInfoDetail();
  148 + qxDeviceInfoDetail.setAlarm(false);
  149 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  150 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  151 + switch (lampState) {
  152 + case 0:
  153 + qxDeviceInfoDetail.setStatus("OFF");
  154 + break;
  155 + case 1:
  156 + qxDeviceInfoDetail.setStatus("ERROR");
  157 + qxDeviceInfoDetail.setAlarm(true);
  158 + break;
  159 + case 2:
  160 + qxDeviceInfoDetail.setStatus("STAND");
  161 + break;
  162 + case 3:
  163 + qxDeviceInfoDetail.setStatus("RUN");
  164 + //先从缓存里面拿token信息
  165 + break;
  166 + default:
  167 + continue;
  168 + }
  169 +
  170 + if (StringUtils.isNotBlank(startTime)) {
  171 + try {
  172 + qxDeviceInfoDetail.setStartTime(dateFormat.parse(startTime));
  173 + } catch (Exception e) {
  174 + log.error("时间格式出错");
  175 + qxDeviceInfoDetail.setStartTime(new Date());
  176 + }
  177 + } else {
  178 + qxDeviceInfoDetail.setStartTime(new Date());
  179 + }
  180 +
  181 + qxDeviceInfoDetail.setDtuSn(dtuSn);
  182 + qxDeviceInfoDetailMap.put(dtuSn, qxDeviceInfoDetail);
  183 + qxAddDeviceInfoDetails.add(qxDeviceInfoDetail);
  184 + }
  185 + }
  186 +
  187 + //将数据同步到IOT平台
  188 + Map<String, String> qxParam = new HashMap<>(2);
  189 + qxParam.put("username", iotUserName);
  190 + qxParam.put("password", iotPassword);
  191 +
  192 + HttpPost qxHttpPost = new HttpPost(iotTokenUrl);
  193 + String qxResult = sendPost(qxHttpPost, JSON.toJSONString(qxParam));
  194 + if (StringUtils.isBlank(qxResult)) {
  195 + return;
  196 + }
  197 + Map<String, Object> qxRes = JSON.parseObject(qxResult, new TypeReference<Map<String, Object>>() {
  198 + });
  199 +
  200 + String qxAccessToken = (String) qxRes.get("token");
  201 + if (StringUtils.isBlank(qxAccessToken)) {
  202 + return;
  203 + }
  204 +
  205 + BasicHeader qxAuthorization = new BasicHeader("X-Authorization", "Bearer " + qxAccessToken);
  206 + if (!CollectionUtils.isEmpty(qxDeviceInfos)) {
  207 + HttpPost qxDeviceInfoPost = new HttpPost(iotDeviceInfoUrl);
  208 + qxDeviceInfoPost.addHeader(qxAuthorization);
  209 + for (QxDeviceInfo qxDeviceInfo : qxDeviceInfos) {
  210 + // todo
  211 + String syncDeviceInfo = sendPost(qxDeviceInfoPost, JSON.toJSONString(qxDeviceInfo));
  212 + //log.info("同步设备信息 syncDeviceInfo:{}", syncDeviceInfo);
  213 + }
  214 + }
  215 +
  216 + if (!CollectionUtils.isEmpty(qxAddDeviceInfoDetails)) {
  217 + for (QxDeviceInfoDetail qxDeviceInfoDetail : qxAddDeviceInfoDetails) {
  218 + String qxDeviceInfoDetailUrlStr = iotDeviceDetailUrl + qxDeviceInfoDetail.getDtuSn() + "/telemetry";
  219 + HttpPost qxDeviceInfoDetailPost = new HttpPost(qxDeviceInfoDetailUrlStr);
  220 + qxDeviceInfoDetailPost.addHeader(qxAuthorization);
  221 + String syncDeviceInfoDetail = sendPost(qxDeviceInfoDetailPost, JSON.toJSONString(qxDeviceInfoDetail));
  222 + }
  223 + }
  224 + }
  225 +
  226 + public String getDeviceInfoDetail(String dtuSn) {
  227 + String accessToken = getAccessToken();
  228 + Map<String, String> dtuSnOb = new HashMap<>(1);
  229 + dtuSnOb.put("dtuSn", dtuSn);
  230 + Map<String, String> headerMap = new HashMap<>(1);
  231 + headerMap.put("Authorization", "Bearer " + accessToken);
  232 + String deviceInfoDetail = sendRequestGet(deviceDetailUrl, dtuSnOb, headerMap);
  233 + if (StringUtils.isBlank(deviceInfoDetail)) {
  234 + return null;
  235 + }
  236 +
  237 + Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetail,
  238 + new TypeReference<>() {
  239 + });
  240 + Integer deviceInfoDetailCode = (Integer) deviceInfoDetailMap.get("code");
  241 + if (deviceInfoDetailCode != 200) {
  242 + return null;
  243 + }
  244 +
  245 + JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
  246 + if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
  247 + return null;
  248 + }
  249 +
  250 + JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
  251 + //灯详情数据
  252 + //灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
  253 + Integer lampState = deviceInfoDetailJson.getInteger("lampState");
  254 + if (lampState == null) {
  255 + return null;
  256 + }
  257 +
  258 + return deviceInfoDetail;
  259 + }
  260 +
  261 + public String getDeviceInfo() {
  262 + String accessToken = getAccessToken();
  263 + // 初始化headerMap并设置Authorization
  264 + Map<String, String> headerMap = new HashMap<>(1);
  265 + headerMap.put("Authorization", "Bearer " + accessToken);
  266 +
  267 + Map<String, String> paramsMap = new HashMap<>();
  268 + paramsMap.put("groupName", "怀宁县一诺纸业有限公司");
  269 +
  270 + // 第一次请求设备信息
  271 + String deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  272 +
  273 + // 检查设备信息是否为空
  274 + if (StringUtils.isBlank(deviceResult)) {
  275 + return null;
  276 + }
  277 +
  278 + // 解析设备信息
  279 + Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  280 + });
  281 + Integer deviceInfoCode = (Integer) deviceInfos.get("code");
  282 +
  283 + // 如果code不为200,可能是accessToken失效,重新获取token并重试
  284 + if (deviceInfoCode != 200) {
  285 + accessToken = getAccessToken();
  286 + if (StringUtils.isEmpty(accessToken)) {
  287 + return null;
  288 + }
  289 +
  290 + // 更新headerMap中的Authorization
  291 + headerMap.put("Authorization", "Bearer " + accessToken);
  292 +
  293 + // 第二次请求设备信息
  294 + deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
  295 + if (StringUtils.isBlank(deviceResult)) {
  296 + return null;
  297 + }
  298 +
  299 + // 重新解析设备信息
  300 + deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
  301 + });
  302 + deviceInfoCode = (Integer) deviceInfos.get("code");
  303 +
  304 + // 如果第二次请求仍然失败,返回错误信息
  305 + if (deviceInfoCode != 200) {
  306 + return null;
  307 + }
  308 + }
  309 +
  310 + // 返回成功的设备信息
  311 + return deviceResult;
  312 + }
  313 +
  314 + private String getAccessToken() {
  315 + String accessToken = "";
  316 + String redisKey = "device_token";
  317 + if (StringUtils.isNotBlank(redisTemplate.opsForValue().get(redisKey)) && redisTemplate.getExpire(redisKey) > 0) {
  318 + return redisTemplate.opsForValue().get(redisKey);
  319 + }
  320 +
  321 + Map<String, String> param = new HashMap<>(2);
  322 + param.put("username", deviceUserName);
  323 + param.put("password", devicePassword);
  324 + HttpPost httpPost = new HttpPost(deviceTokenUrl);
  325 + String result = sendPost(httpPost, JSON.toJSONString(param));
  326 + if (StringUtils.isBlank(result)) {
  327 + return accessToken;
  328 + }
  329 +
  330 + Map<String, Object> res = JSON.parseObject(result, new TypeReference<>() {
  331 + });
  332 +
  333 + Integer code = (Integer) res.get("code");
  334 + if (code == 200) {
  335 + JSONObject data = (JSONObject) res.get("data");
  336 + accessToken = (String) data.get("token");
  337 + redisTemplate.opsForValue().set(redisKey, accessToken, 3600, TimeUnit.SECONDS); // 一小时过期
  338 + }
  339 +
  340 + return accessToken;
  341 + }
  342 +
  343 + public static String sendRequestGet(String url, Map<String, String> params, Map<String, String> header) {
  344 + //实例化httpclient
  345 + CloseableHttpClient httpclient = HttpClients.createDefault();
  346 + url = builderUrl(url, params);
  347 + //请求结果
  348 + String content = "";
  349 + //实例化get方法
  350 + HttpGet httpget = new HttpGet(url);
  351 + if (!CollectionUtils.isEmpty(header)) {
  352 + for (Map.Entry<String, String> entry : header.entrySet()) {
  353 + httpget.setHeader(entry.getKey(), entry.getValue());
  354 + }
  355 + }
  356 +
  357 + try (CloseableHttpResponse response = httpclient.execute(httpget)) {
  358 +
  359 + //执行get方法
  360 + if (response.getStatusLine().getStatusCode() == 200) {
  361 + content = EntityUtils.toString(response.getEntity(), "UTF-8");
  362 + }
  363 + } catch (IOException e) {
  364 + log.error("sendRequest---GET Error!", e);
  365 + }
  366 + return content;
  367 + }
  368 +
  369 + private static String builderUrl(String url, Map<String, String> params) {
  370 + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
  371 + if (!CollectionUtils.isEmpty(params)) {
  372 + MultiValueMap<String, String> paramsValue = new LinkedMultiValueMap<>();
  373 + for (Map.Entry<String, String> entry : params.entrySet()) {
  374 + paramsValue.add(entry.getKey(), entry.getValue());
  375 + }
  376 +
  377 + uriBuilder = uriBuilder.queryParams(paramsValue);
  378 + }
  379 +
  380 + return uriBuilder.toUriString();
  381 + }
  382 +
  383 + private String sendPost(HttpPost httpPost, String jsonData) {
  384 + CloseableHttpClient httpClient = HttpClients.createDefault();
  385 + StringEntity entity = new StringEntity(jsonData, ContentType.create("application/json", Consts.UTF_8));
  386 + httpPost.setEntity(entity);
  387 + String result = null;
  388 + try {
  389 + CloseableHttpResponse execute = httpClient.execute(httpPost);
  390 + HttpEntity res = execute.getEntity();
  391 + InputStream is = res.getContent();
  392 + int len;
  393 + byte[] buf = new byte[128];
  394 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  395 + while ((len = is.read(buf)) != -1) {
  396 + byteArrayOutputStream.write(buf, 0, len);
  397 + }
  398 + result = byteArrayOutputStream.toString();
  399 + } catch (IOException e) {
  400 + e.printStackTrace();
  401 + }
  402 + return result;
  403 + }
  404 +}
@@ -27,6 +27,12 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler { @@ -27,6 +27,12 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler {
27 private YjhbDevicePullService yjhbDevicePullService; 27 private YjhbDevicePullService yjhbDevicePullService;
28 @Resource 28 @Resource
29 private XpDeviceReportService xpDeviceReportService; 29 private XpDeviceReportService xpDeviceReportService;
  30 + @Resource
  31 + private YnzyDevicePullService ynzyDevicePullService;
  32 + @Resource
  33 + private AhhmDevicePullService ahhmDevicePullService;
  34 + @Resource
  35 + private AhajrDevicePullService ahajrDevicePullService;
30 36
31 @Override 37 @Override
32 protected String getZoneName() { 38 protected String getZoneName() {
@@ -46,6 +52,9 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler { @@ -46,6 +52,9 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler {
46 shzzDevicePullService.pullDeviceAndPushToIot(); 52 shzzDevicePullService.pullDeviceAndPushToIot();
47 yjhbDevicePullService.pullDeviceAndPushToIot(); 53 yjhbDevicePullService.pullDeviceAndPushToIot();
48 kjzsDevicePullService.pullDeviceAndPushToIot(); 54 kjzsDevicePullService.pullDeviceAndPushToIot();
  55 + ynzyDevicePullService.pullDeviceAndPushToIot();
  56 + ahhmDevicePullService.pullDeviceAndPushToIot();
  57 + ahajrDevicePullService.pullDeviceAndPushToIot();
49 Thread.sleep(1000); 58 Thread.sleep(1000);
50 } catch (Exception e) { 59 } catch (Exception e) {
51 logError(taskName, e); 60 logError(taskName, e);
@@ -38,7 +38,7 @@ scheduler: @@ -38,7 +38,7 @@ scheduler:
38 pj: 38 pj:
39 push: "0 0/10 * * * ?" 39 push: "0 0/10 * * * ?"
40 jmdq: 40 jmdq:
41 - pull: "0 0/5 * * * ?" 41 + pull: "0 0/1 * * * ?"
42 push: "0 0/2 * * * ?" 42 push: "0 0/2 * * * ?"
43 nanqiao: 43 nanqiao:
44 pull: "0 0/1 * * * ?" 44 pull: "0 0/1 * * * ?"
@@ -69,7 +69,10 @@ hn: @@ -69,7 +69,10 @@ hn:
69 'f82530a0-93e4-4aeb-9339-f5b6d1127840', 69 'f82530a0-93e4-4aeb-9339-f5b6d1127840',
70 '752a7621-b59b-477c-b15e-e06d412e02d5', 70 '752a7621-b59b-477c-b15e-e06d412e02d5',
71 '00690478-b836-4986-88fd-1dd8cb87ed1d', 71 '00690478-b836-4986-88fd-1dd8cb87ed1d',
72 - '7985002f-53c5-41bf-98d6-58ef422dadfd' 72 + '7985002f-53c5-41bf-98d6-58ef422dadfd',
  73 + '9de73a7a-61e7-481f-8aab-df39253770d8',
  74 + 'eaa6f152-9ef5-4ad2-b12c-ac10e47a110e',
  75 + '378f6df7-6a72-4c6d-8d09-b14834b3e824'
73 ) 76 )
74 UNION all 77 UNION all
75 78
@@ -287,6 +290,39 @@ kjzs: @@ -287,6 +290,39 @@ kjzs:
287 infoUrl: "https://iot.hzzlyun.com/api/yt/device" 290 infoUrl: "https://iot.hzzlyun.com/api/yt/device"
288 detailUrl: "https://iot.hzzlyun.com/api/v1/" 291 detailUrl: "https://iot.hzzlyun.com/api/v1/"
289 292
  293 +ahajr:
  294 + iot:
  295 + organizeId: "378f6df7-6a72-4c6d-8d09-b14834b3e824"
  296 + profileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  297 + deviceProfileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  298 + userName: "ahajr"
  299 + password: "Ahajr@123.com"
  300 + tokenUrl: "https://iot.hzzlyun.com/api/auth/login"
  301 + infoUrl: "https://iot.hzzlyun.com/api/yt/device"
  302 + detailUrl: "https://iot.hzzlyun.com/api/v1/"
  303 +
  304 +ynzy:
  305 + iot:
  306 + organizeId: "eaa6f152-9ef5-4ad2-b12c-ac10e47a110e"
  307 + profileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  308 + deviceProfileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  309 + userName: "ynzy"
  310 + password: "Ynzy@123.com"
  311 + tokenUrl: "https://iot.hzzlyun.com/api/auth/login"
  312 + infoUrl: "https://iot.hzzlyun.com/api/yt/device"
  313 + detailUrl: "https://iot.hzzlyun.com/api/v1/"
  314 +
  315 +ahhm:
  316 + iot:
  317 + organizeId: "9de73a7a-61e7-481f-8aab-df39253770d8"
  318 + profileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  319 + deviceProfileId: "f2292f60-f738-11f0-9cb8-e3376d1e7978"
  320 + userName: "ahhm"
  321 + password: "Ahhm@123.com"
  322 + tokenUrl: "https://iot.hzzlyun.com/api/auth/login"
  323 + infoUrl: "https://iot.hzzlyun.com/api/yt/device"
  324 + detailUrl: "https://iot.hzzlyun.com/api/v1/"
  325 +
290 device: 326 device:
291 token: 327 token:
292 url: "https://iotgc.cniot.vip/auth/token" 328 url: "https://iotgc.cniot.vip/auth/token"