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();
+ }
+
+
+}