Browse Source

lwm2m - execute with params

pull/14881/head
nickAS21 7 months ago
parent
commit
69afda634b
  1. 9
      application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java
  2. 51
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java
  3. 12
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java
  4. 6
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java
  5. 27
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcExecuteRequest.java

9
application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java

@ -160,7 +160,14 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl
if (!arguments.isEmpty())
withArguments = " with arguments " + arguments;
log.info("Execute on Device resource /{}/{}/{} {}", getModel().id, getId(), resourceId, withArguments);
return ExecuteResponse.success();
switch (resourceId) {
case 4:
return ExecuteResponse.success();
case 5:
return ExecuteResponse.success();
default:
return super.execute(identity, resourceId, arguments);
}
}
@Override

51
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java

@ -29,6 +29,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INST
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_4;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_5;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_8;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_9;
@ -90,14 +91,54 @@ public class RpcLwm2mIntegrationExecuteTest extends AbstractRpcLwM2MIntegrationT
/**
* execute_resource_with_parameters (execute reboot after 60 seconds on device)
* Execute {"id":"3/0/4","value":60}
* execute_resource_with_parameters (execute reboot if digit = 5 on device)
* Execute {"id":"3/0/4","value":5}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteResourceWithParametersById_Result_CHANGED() throws Exception {
public void testExecuteResourceWithParametersOnlyOneDigitValueNullById_Result_Ok() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + RESOURCE_ID_4;
Object expectedValue = 60;
Object expectedValue = 5;
String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* execute_resource_with_parameters (execute Factory Reset if digit = 2 -> after 60 seconds on device)
* Execute {"id":"3/0/5","value":"2='60'"}
*/
@Test
public void testExecuteResourceWithParametersDigit2Value60ById_Result_Ok() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + RESOURCE_ID_5;
Object expectedValue = "2='60'";
String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* execute_resource_with_parameters (execute Factory Reset after connect with link on device)
* Execute {"id":"3/0/5","value":"2,0='https://thingsboard.io/docs/reference/lwm2m-api/'"}
*/
@Test
public void testExecuteResourceWithParametersDigit2_0_ValueLinkById_Result_Ok() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + RESOURCE_ID_5;
Object expectedValue = "2,0='https://thingsboard.io/docs/reference/lwm2m-api/'";
String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* execute_resource_with_parameters (execute Factory Reset after connect with link on device)
* Execute {"id":"3/0/5","value":"0,1,2,3,4,5,6,7,8,9"}
*/
@Test
public void testExecuteResourceWithParametersDigitManyValueNullById_Result_Ok() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + RESOURCE_ID_5;
Object expectedValue = "0,1,2,3,4,5,6,7,8,9";
String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
@ -178,7 +219,7 @@ public class RpcLwm2mIntegrationExecuteTest extends AbstractRpcLwM2MIntegrationT
}
private String sendRPCExecuteWithValueById(String path, Object value) throws Exception {
String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\", \"value\": " + value + " }}";
String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\", \"value\": \"" + value + "\"}}";
return doPostAsync("/api/plugins/rpc/twoway/" + lwM2MTestClient.getDeviceIdStr(), setRpcRequest, String.class, status().isOk());
}

12
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java

@ -50,6 +50,8 @@ import org.eclipse.leshan.core.request.SimpleDownlinkRequest;
import org.eclipse.leshan.core.request.WriteAttributesRequest;
import org.eclipse.leshan.core.request.WriteCompositeRequest;
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.request.argument.Arguments;
import org.eclipse.leshan.core.request.argument.InvalidArgumentException;
import org.eclipse.leshan.core.request.exception.ClientSleepingException;
import org.eclipse.leshan.core.request.exception.InvalidRequestException;
import org.eclipse.leshan.core.request.exception.TimeoutException;
@ -116,6 +118,7 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
import static org.thingsboard.server.common.transport.util.JsonUtils.isBase64;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.createModelsDefault;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.equalsResourceTypeGetSimpleName;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.getVerFromPathIdVerOrId;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.validateVersionedId;
@ -281,8 +284,11 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
} else if (resourceModelExecute.operations.isExecutable()) {
ExecuteRequest downlink;
if (request.getParams() != null && !resourceModelExecute.multiple) {
downlink = new ExecuteRequest(request.getObjectId(), (String) this.converter.convertValue(request.getParams(),
resourceModelExecute.type, ResourceModel.Type.STRING, new LwM2mPath(request.getObjectId())));
Object params = request.getParams();
ResourceModel.Type resourceModel = resourceModelExecute.type == ResourceModel.Type.NONE ? equalsResourceTypeGetSimpleName(params) : resourceModelExecute.type;
String args = (String) this.converter.convertValue(params, resourceModel, ResourceModel.Type.STRING, new LwM2mPath(request.getObjectId()));
Arguments arguments = Arguments.parse(args);
downlink = new ExecuteRequest(request.getObjectId(), arguments);
} else {
downlink = new ExecuteRequest(request.getObjectId());
}
@ -290,7 +296,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
} else {
callback.onValidationError(request.toString(), "Resource with " + request.getVersionedId() + " is not executable.");
}
} catch (InvalidRequestException e) {
} catch (InvalidRequestException | InvalidArgumentException e) {
callback.onValidationError(request.toString(), e.getMessage());
}
}

6
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java

@ -241,7 +241,13 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
}
private void sendExecuteRequest(LwM2mClient client, TransportProtos.ToDeviceRpcRequestMsg requestMsg, String versionedId) {
RpcExecuteRequest requestBody = JacksonUtil.fromString(requestMsg.getParams(), RpcExecuteRequest.class);
TbLwM2MExecuteRequest downlink = TbLwM2MExecuteRequest.builder().versionedId(versionedId).timeout(clientContext.getRequestTimeout(client)).build();
if (!requestMsg.getParams().isEmpty()) {
downlink = TbLwM2MExecuteRequest.builder().versionedId(versionedId)
.params(requestBody.getValue())
.timeout(clientContext.getRequestTimeout(client)).build();
}
var mainCallback = new TbLwM2MExecuteCallback(logService, client, versionedId);
var rpcCallback = new RpcEmptyResponseCallback<>(transportService, client, requestMsg, mainCallback);
downlinkHandler.sendExecuteRequest(client, downlink, rpcCallback);

27
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcExecuteRequest.java

@ -0,0 +1,27 @@
/**
* Copyright © 2016-2026 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.rpc;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class RpcExecuteRequest extends LwM2MRpcRequestHeader {
private Object value;
}
Loading…
Cancel
Save