From 496eb7c450104349841c0d4cb02686a764e251df Mon Sep 17 00:00:00 2001 From: zhangzhicheng Date: Fri, 26 Jul 2024 17:40:22 +0800 Subject: [PATCH] =?UTF-8?q?iot=E4=BA=A4=E4=BA=92=E5=A4=A7=E8=87=B4?= =?UTF-8?q?=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-admin/pom.xml | 19 ++ .../org/dromara/web/config/CacheConfig.java | 60 +++++++ .../org/dromara/web/service/IotService.java | 168 ++++++++++++++++++ .../service/impl/EqEquipmentServiceImpl.java | 71 ++------ .../src/main/resources/application-dev.yml | 2 +- .../java/org/dromara/test/IotHttpTest.java | 141 +++++++++++++++ .../test/java/org/dromara/test/IotTest.java | 48 +++++ 7 files changed, 448 insertions(+), 61 deletions(-) create mode 100644 ruoyi-admin/src/main/java/org/dromara/web/config/CacheConfig.java create mode 100644 ruoyi-admin/src/main/java/org/dromara/web/service/IotService.java create mode 100644 ruoyi-admin/src/test/java/org/dromara/test/IotHttpTest.java create mode 100644 ruoyi-admin/src/test/java/org/dromara/test/IotTest.java diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 9e08f88a9..924518fac 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -97,6 +97,12 @@ test + + org.javatuples + javatuples + 1.2 + + @@ -109,6 +115,12 @@ + + org.thingsboard + rest-client + 3.5.1 + + @@ -143,4 +155,11 @@ + + + thingsboard + https://repo.thingsboard.io/artifactory/libs-release-public + + + diff --git a/ruoyi-admin/src/main/java/org/dromara/web/config/CacheConfig.java b/ruoyi-admin/src/main/java/org/dromara/web/config/CacheConfig.java new file mode 100644 index 000000000..d250aee87 --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/config/CacheConfig.java @@ -0,0 +1,60 @@ +package org.dromara.web.config; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Configuration +public class CacheConfig { + + + + @Bean(name = "booleanCache") + public Cache booleanCache() { + // 创建guava cache + return Caffeine.newBuilder() + //cache的初始容量 + .initialCapacity(10) + //cache最大缓存数 + .maximumSize(48) + .build(); + } + + + /** + * 2小时超时 + */ + @Bean(name = "tokenCache") + public Cache tokenCache() { + // 创建guava cache + return Caffeine.newBuilder() + //cache的初始容量 + .initialCapacity(2) + //cache最大缓存数 + .maximumSize(5) + //设置写缓存后n秒钟过期 + .expireAfterWrite(2, TimeUnit.HOURS) + //设置读写缓存后n秒钟过期,实际很少用到,类似于expireAfterWrite + //.expireAfterAccess(60, TimeUnit.SECONDS) + .build(); + } + + + @Bean + public Cache> cacheCommonMapString() { + // 创建guava cache + return Caffeine.newBuilder() + //cache的初始容量 + .initialCapacity(20) + //cache最大缓存数 + .maximumSize(200) + .build(); + } + + + +} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/IotService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/IotService.java new file mode 100644 index 000000000..37ae5dfc6 --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/IotService.java @@ -0,0 +1,168 @@ +package org.dromara.web.service; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.github.benmanes.caffeine.cache.Cache; +import org.dromara.web.config.CommonYmlConfig; +import org.dromara.web.device.DeviceCtlDto; +import org.javatuples.Pair; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName : IotService + * @Author : ZZC + * @Date : 2024/7/26 16:34 + * @Discription : iot相关服务 + **/ +@Service +public class IotService { + @Resource + private Cache tokenCache; + + + + + /** + * 设备控制指令 + * @param deviceCode + * @param cmd + * @return + */ + public String httpCtlPostSend(String deviceCode,String cmd){ + DeviceCtlDto dto = new DeviceCtlDto(); + DeviceCtlDto.Params params = dto.getParams(); + params.setCommand(cmd); + dto.setParams(params); + Map paramMap = new HashMap<>(); + paramMap.put("deviceId",deviceCode); + return postSendWithParam(CommonYmlConfig.URL_IOT_OPERATE, paramMap, JSON.toJSONString(dto)); + } + + /** + * 获取设备信息 + * @param deviceCode + * @return + */ + public String httpTelemetryGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("entityType","DEVICE"); + map.put("entityId",deviceCode); + return getSend(CommonYmlConfig.URL_IOT_TELEMETRY, map); + } + + /** + * 获取服务端属性信息 + * @param deviceCode + * @return + */ + public String httpServerGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("entityType","DEVICE"); + map.put("entityId",deviceCode); + return getSend(CommonYmlConfig.URL_IOT_SERVER_ATTRIBUTE, map); + } + + + /** + * 获取设备信息 + * @param deviceCode + * @return + */ + public String httpDeviceGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("deviceId",deviceCode); + return getSend(CommonYmlConfig.URL_IOT_DEVICE, map); + } + + + public String getToken() { + String token = tokenCache.getIfPresent("token"); + if (token == null){ + token = login(); + tokenCache.put("token", token); + } + return token; + } + + private String login() { + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token; + String longinUrl = "/api/auth/login"; + Map map = new HashMap<>(); + map.put("username", "tenant@thingsboard.org"); + map.put("password", "tenant"); + String loginPath = baseUrl + longinUrl; + HttpRequest request = HttpUtil.createPost(loginPath); + HttpResponse execute = request.body(JSON.toJSONString(map)).execute(); + String loginBody = execute.body(); + JSONObject jsonObject = JSONObject.parseObject(loginBody); + token = jsonObject.getString("token"); + return token; + } + + /** + * 发送get请求 + * @param contextPath + * @param pathParam + * @return + */ + public String getSend(String contextPath, Map pathParam) { + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token = getToken(); + for (Map.Entry entry : pathParam.entrySet()) { + contextPath = contextPath.replace("{"+entry.getKey()+"}",entry.getValue()); + } + String url = baseUrl + contextPath; + HttpRequest httpRequest = HttpUtil.createGet(url).header("X-Authorization", "Bearer " + token); + HttpResponse resultResponse = httpRequest.execute(); + return resultResponse.body(); + } + + /** + * 发送get请求 + * @param contextPath + * @param pathParam + * @return + */ + public String getSendWithParam(String contextPath, Map pathParam, Map paramMap) { + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token = getToken(); + for (Map.Entry entry : pathParam.entrySet()) { + contextPath = contextPath.replace("{"+entry.getKey()+"}",entry.getValue()); + } + String url = baseUrl + contextPath; + HttpRequest httpRequest = HttpUtil.createGet(url).header("X-Authorization", "Bearer " + token); + httpRequest.form(paramMap); + HttpResponse resultResponse = httpRequest.execute(); + return resultResponse.body(); + } + + + /** + * 发送post请求 + * @param contextPath + * @param pathParam + * @return + */ + public String postSendWithParam(String contextPath, Map pathParam, String paramBody) { + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token = getToken(); + for (Map.Entry entry : pathParam.entrySet()) { + contextPath = contextPath.replace("{"+entry.getKey()+"}",entry.getValue()); + } + String url = baseUrl + contextPath; + HttpRequest httpRequest = HttpUtil.createPost(url).header("X-Authorization", "Bearer " + token); + httpRequest.body(paramBody); + HttpResponse resultResponse = httpRequest.execute(); + return resultResponse.body(); + } + +} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentServiceImpl.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentServiceImpl.java index bc7dfe56c..b9c5a73a6 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentServiceImpl.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentServiceImpl.java @@ -18,6 +18,7 @@ import org.dromara.web.domain.bo.EqAppHomeBo; import org.dromara.web.domain.bo.EqDeviceCmdBo; import org.dromara.web.domain.bo.EqDeviceSetBo; import org.dromara.web.domain.vo.EqEquipmentStatusVo; +import org.dromara.web.service.IotService; import org.springframework.stereotype.Service; import org.dromara.web.domain.bo.EqEquipmentBo; import org.dromara.web.domain.vo.EqEquipmentVo; @@ -41,6 +42,8 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService { private final EqEquipmentMapper baseMapper; + private final IotService iotService; + /** * 查询设备信息 * @@ -162,7 +165,7 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService { return "指令类型错误"; } //增加操作次数 更新到设备表中 - return httpCtlPostSend(bo.getEquipmentCode(),cmd); + return iotService.httpCtlPostSend(bo.getEquipmentCode(),cmd); } @Override @@ -192,7 +195,7 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService { cmd = cmd.replace(DeviceSetCmd.MODEL,bo.getOperateValue()+""); } //增加操作次数 更新到设备表中 - return httpCtlPostSend(bo.getEquipmentCode(),cmd); + return iotService.httpCtlPostSend(bo.getEquipmentCode(),cmd); } @Override @@ -202,14 +205,14 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService { result.setEquipmentCode(bo.getEquipmentCode()); //获取服务属性状态 - String serverMsg = httpServerGetSend(bo.getEquipmentCode()); + String serverMsg = iotService.httpServerGetSend(bo.getEquipmentCode()); DeviceServerMsgDto serverMsgDto = JSONObject.parseObject(serverMsg, DeviceServerMsgDto.class); if (!serverMsgDto.getLineStatus()){ result.setLineStatus(0);//离线 return result; } //获取遥测数据 - String telemetryMsg = httpTelemetryGetSend(bo.getEquipmentCode()); + String telemetryMsg = iotService.httpTelemetryGetSend(bo.getEquipmentCode()); DeviceMsgDto deviceMsgDto = JSONObject.parseObject(telemetryMsg, DeviceMsgDto.class); BeanUtil.copyProperties(deviceMsgDto,result,true); return result; @@ -218,66 +221,14 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService { @Override public Boolean bindDevice(EqEquipmentBo eqEquipmentBo) { String equipmentCode = eqEquipmentBo.getEquipmentCode(); + String result = iotService.httpDeviceGetSend(equipmentCode); + //判断是否获取到信息 + //获取到信息之后 获取设备状态类信息 + //封装 调用设备数据进行保存 return null; } - /** - * 设备控制指令 - * @param deviceCode - * @param cmd - * @return - */ - private String httpCtlPostSend(String deviceCode,String cmd){ - DeviceCtlDto dto = new DeviceCtlDto(); -// dto.setMethod();//todo 方法 - DeviceCtlDto.Params params = dto.getParams(); - params.setCommand(cmd); - dto.setParams(params); - // todo 登录相关 token - String url = CommonYmlConfig.URL_IOT_BASEURL+CommonYmlConfig.URL_IOT_OPERATE; - url = url.replace("{deviceId}",deviceCode) ; - return HttpUtil.post(url, JSON.toJSONString(dto)); - } - - /** - * 获取设备信息 - * @param deviceCode - * @return - */ - private String httpTelemetryGetSend(String deviceCode){ - String url = CommonYmlConfig.URL_IOT_BASEURL+CommonYmlConfig.URL_IOT_TELEMETRY; - url = url.replace("{entityType}","DEVICE") ; - url = url.replace("{entityId}",deviceCode) ; - // todo 登录相关 token - return HttpUtil.get(url); - } - - /** - * 获取服务端属性信息 - * @param deviceCode - * @return - */ - private String httpServerGetSend(String deviceCode){ - String url = CommonYmlConfig.URL_IOT_BASEURL+CommonYmlConfig.URL_IOT_SERVER_ATTRIBUTE; - url = url.replace("{entityType}","DEVICE") ; - url = url.replace("{entityId}",deviceCode) ; - // todo 登录相关 token - return HttpUtil.get(url); - } - - - /** - * 获取设备信息 - * @param deviceCode - * @return - */ - private String httpDeviceGetSend(String deviceCode){ - String url = CommonYmlConfig.URL_IOT_BASEURL+CommonYmlConfig.URL_IOT_DEVICE; - url = url.replace("{deviceId}",deviceCode) ; - // todo 登录相关 token - return HttpUtil.get(url); - } } diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 5f684c275..e8af2d1ce 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -258,7 +258,7 @@ justauth: redirect-uri: ${justauth.address}/social-callback?source=gitlab iot: - baseurl: http://127.0.0.1:4523/m1/4875377-0-default + baseurl: http://118.89.86.111:8080 url: serverAttribute: /api/plugins/telemetry/{entityType}/{entityId}/values/attributes telemetry: /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries diff --git a/ruoyi-admin/src/test/java/org/dromara/test/IotHttpTest.java b/ruoyi-admin/src/test/java/org/dromara/test/IotHttpTest.java new file mode 100644 index 000000000..691820c2a --- /dev/null +++ b/ruoyi-admin/src/test/java/org/dromara/test/IotHttpTest.java @@ -0,0 +1,141 @@ +package org.dromara.test; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.dromara.web.config.CommonYmlConfig; +import org.dromara.web.device.DeviceCtlDto; +import org.dromara.web.service.IotService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.thingsboard.rest.client.RestClient; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** + * 断言单元测试案例 + * + * @author Lion Li + */ +@DisplayName("测试http调用") +@SpringBootTest +public class IotHttpTest { + + @Resource + private IotService iotService; + + @DisplayName("测试http调用") + @Test + public void testHttp() { + String deviceCode = "4cd72020-2b11-11ef-890f-e7ba493dc999"; + String urlIotDevice = CommonYmlConfig.URL_IOT_DEVICE; + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token = iotService.getToken(); + + String url = baseUrl + urlIotDevice; + url = url.replace("{deviceId}",deviceCode) ; + + HttpRequest httpRequest = HttpUtil.createGet(url).header("X-Authorization", "Bearer " + token); + HttpResponse resultResponse = httpRequest.execute(); + String result = resultResponse.body(); + System.out.println(result); + } + + + + private static String test() { + String baseUrl = CommonYmlConfig.URL_IOT_BASEURL; + String token; + String longinUrl = "/api/auth/login"; + Map map = new HashMap<>(); + map.put("username", "tenant@thingsboard.org"); + map.put("password", "tenant"); + String loginPath = baseUrl + longinUrl; + HttpRequest request = HttpUtil.createPost(loginPath); + HttpResponse execute = request.body(JSON.toJSONString(map)).execute(); + String loginBody = execute.body(); + JSONObject jsonObject = JSONObject.parseObject(loginBody); + token = jsonObject.getString("token"); + return token; + } + + @Test + public void testMethod(){ + String deviceCode = "4cd72020-2b11-11ef-890f-e7ba493dc999"; + String cmd = ""; + +// String result = httpCtlPostSend(deviceCode,cmd); +// System.out.println(result); + + String result2 = httpTelemetryGetSend(deviceCode); + System.out.println(result2); + + String result3 = httpDeviceGetSend(deviceCode); + System.out.println(result3); + + String result4 = httpServerGetSend(deviceCode); + System.out.println(result4); + } + + + /** + * 设备控制指令 + * @param deviceCode + * @param cmd + * @return + */ + public String httpCtlPostSend(String deviceCode,String cmd){ + DeviceCtlDto dto = new DeviceCtlDto(); + DeviceCtlDto.Params params = dto.getParams(); + params.setCommand(cmd); + dto.setParams(params); + Map paramMap = new HashMap<>(); + paramMap.put("deviceId",deviceCode); + return iotService.postSendWithParam(CommonYmlConfig.URL_IOT_OPERATE, paramMap, JSON.toJSONString(dto)); + } + + /** + * 获取设备信息 + * @param deviceCode + * @return + */ + public String httpTelemetryGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("entityType","DEVICE"); + map.put("entityId",deviceCode); + return iotService.getSend(CommonYmlConfig.URL_IOT_TELEMETRY, map); + } + + /** + * 获取服务端属性信息 + * @param deviceCode + * @return + */ + public String httpServerGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("entityType","DEVICE"); + map.put("entityId",deviceCode); + return iotService.getSend(CommonYmlConfig.URL_IOT_SERVER_ATTRIBUTE, map); + } + + + /** + * 获取设备信息 + * @param deviceCode + * @return + */ + public String httpDeviceGetSend(String deviceCode){ + Map map = new HashMap<>(); + map.put("deviceId",deviceCode); + return iotService.getSend(CommonYmlConfig.URL_IOT_DEVICE, map); + } + + +} diff --git a/ruoyi-admin/src/test/java/org/dromara/test/IotTest.java b/ruoyi-admin/src/test/java/org/dromara/test/IotTest.java new file mode 100644 index 000000000..3f3f842bb --- /dev/null +++ b/ruoyi-admin/src/test/java/org/dromara/test/IotTest.java @@ -0,0 +1,48 @@ +package org.dromara.test; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.thingsboard.rest.client.RestClient; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.id.DeviceId; + +import java.util.Optional; +import java.util.UUID; + +/** + * 断言单元测试案例 + * + * @author Lion Li + */ +@DisplayName("断言单元测试案例") +public class IotTest { + + @DisplayName("测试 assertEquals 方法") + @Test + public void testAssertEquals() { + // ThingsBoard REST API URL + String url = "http://118.89.86.111:8080/"; + +// Default Tenant Administrator credentials + String username = "tenant@thingsboard.org"; + String password = "tenant"; + +// Creating new rest client and auth with credentials + RestClient client = new RestClient(url); + client.login(username, password); + +// Get information of current logged in user and print it + client.getUser().ifPresent(System.out::println); + DeviceId deviceId = new DeviceId(UUID.fromString("4cd72020-2b11-11ef-890f-e7ba493dc999")); + Optional deviceById = client.getDeviceById(deviceId); + + Assertions.assertTrue(deviceById.isPresent()); + +// Perform logout of current user and close the client + client.logout(); + client.close(); + } + + +}