Commit bacf822f156cb526ee3cf76d22db1e945831e071

Authored by nickAS21
Committed by Andrew Shvayka
1 parent cf405be4

Lwm2m: add Write_Update example #1

@@ -33,7 +33,6 @@ import org.eclipse.leshan.core.request.ContentFormat; @@ -33,7 +33,6 @@ import org.eclipse.leshan.core.request.ContentFormat;
33 import org.eclipse.leshan.core.request.WriteRequest; 33 import org.eclipse.leshan.core.request.WriteRequest;
34 import org.eclipse.leshan.core.response.ReadResponse; 34 import org.eclipse.leshan.core.response.ReadResponse;
35 import org.eclipse.leshan.core.util.NamedThreadFactory; 35 import org.eclipse.leshan.core.util.NamedThreadFactory;
36 -import org.eclipse.leshan.server.californium.LeshanServer;  
37 import org.eclipse.leshan.server.registration.Registration; 36 import org.eclipse.leshan.server.registration.Registration;
38 import org.springframework.context.annotation.Lazy; 37 import org.springframework.context.annotation.Lazy;
39 import org.springframework.stereotype.Service; 38 import org.springframework.stereotype.Service;
@@ -102,7 +101,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle @@ -102,7 +101,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle
102 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.READ; 101 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.READ;
103 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; 102 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
104 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_REPLACE; 103 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_REPLACE;
105 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_UPDATE;  
106 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.SERVICE_CHANNEL; 104 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.SERVICE_CHANNEL;
107 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertJsonArrayToSet; 105 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertJsonArrayToSet;
108 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromIdVerToObjectId; 106 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromIdVerToObjectId;
@@ -490,15 +488,17 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -490,15 +488,17 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
490 if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) { 488 if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) {
491 lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " + 489 lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " +
492 lwm2mClientRpcRequest.keyNameKey + " is null or bad format"); 490 lwm2mClientRpcRequest.keyNameKey + " is null or bad format");
493 - } else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper() 491 + }
  492 + /**
  493 + * EXECUTE && WRITE_REPLACE - only for Resource or ResourceInstance
  494 + */
  495 + else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper()
494 || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper()) 496 || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper())
495 && lwm2mClientRpcRequest.getTargetIdVer() != null 497 && lwm2mClientRpcRequest.getTargetIdVer() != null
496 && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource() 498 && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource()
497 || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) { 499 || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) {
498 lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey 500 lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey
499 + ". Only Resource or ResourceInstance can be this operation"); 501 + ". Only Resource or ResourceInstance can be this operation");
500 - } else if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()) {  
501 - lwm2mClientRpcRequest.setErrorMsg("Procedures In Development...");  
502 } 502 }
503 } else { 503 } else {
504 lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format."); 504 lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format.");
@@ -930,7 +930,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -930,7 +930,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
930 * @param request - 930 * @param request -
931 */ 931 */
932 public void onWriteResponseOk(Registration registration, String path, WriteRequest request) { 932 public void onWriteResponseOk(Registration registration, String path, WriteRequest request) {
933 - this.updateResourcesValue(registration, ((LwM2mResource) request.getNode()), path); 933 + if (request.getNode() instanceof LwM2mResource) {
  934 + this.updateResourcesValue(registration, ((LwM2mResource) request.getNode()), path);
  935 + }
  936 + else if (request.getNode() instanceof LwM2mObjectInstance) {
  937 + ((LwM2mObjectInstance) request.getNode()).getResources().forEach((resId, resource) -> {
  938 + this.updateResourcesValue(registration, resource, path+ "/" + resId);
  939 + });
  940 + }
  941 +
934 } 942 }
935 943
936 /** 944 /**
@@ -16,13 +16,13 @@ @@ -16,13 +16,13 @@
16 package org.thingsboard.server.transport.lwm2m.server; 16 package org.thingsboard.server.transport.lwm2m.server;
17 17
18 import lombok.RequiredArgsConstructor; 18 import lombok.RequiredArgsConstructor;
19 -import lombok.SneakyThrows;  
20 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
21 import org.eclipse.californium.core.coap.CoAP; 20 import org.eclipse.californium.core.coap.CoAP;
22 import org.eclipse.californium.core.coap.Response; 21 import org.eclipse.californium.core.coap.Response;
23 import org.eclipse.leshan.core.model.ResourceModel; 22 import org.eclipse.leshan.core.model.ResourceModel;
24 import org.eclipse.leshan.core.node.LwM2mNode; 23 import org.eclipse.leshan.core.node.LwM2mNode;
25 import org.eclipse.leshan.core.node.LwM2mPath; 24 import org.eclipse.leshan.core.node.LwM2mPath;
  25 +import org.eclipse.leshan.core.node.LwM2mResource;
26 import org.eclipse.leshan.core.node.LwM2mSingleResource; 26 import org.eclipse.leshan.core.node.LwM2mSingleResource;
27 import org.eclipse.leshan.core.node.ObjectLink; 27 import org.eclipse.leshan.core.node.ObjectLink;
28 import org.eclipse.leshan.core.observation.Observation; 28 import org.eclipse.leshan.core.observation.Observation;
@@ -46,10 +46,8 @@ import org.eclipse.leshan.core.response.WriteAttributesResponse; @@ -46,10 +46,8 @@ import org.eclipse.leshan.core.response.WriteAttributesResponse;
46 import org.eclipse.leshan.core.response.WriteResponse; 46 import org.eclipse.leshan.core.response.WriteResponse;
47 import org.eclipse.leshan.core.util.Hex; 47 import org.eclipse.leshan.core.util.Hex;
48 import org.eclipse.leshan.core.util.NamedThreadFactory; 48 import org.eclipse.leshan.core.util.NamedThreadFactory;
49 -import org.eclipse.leshan.server.californium.LeshanServer;  
50 import org.eclipse.leshan.server.registration.Registration; 49 import org.eclipse.leshan.server.registration.Registration;
51 import org.springframework.stereotype.Service; 50 import org.springframework.stereotype.Service;
52 -import org.thingsboard.server.common.transport.TransportService;  
53 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 51 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
54 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; 52 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
55 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 53 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
@@ -59,6 +57,7 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; @@ -59,6 +57,7 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
59 57
60 import javax.annotation.PostConstruct; 58 import javax.annotation.PostConstruct;
61 import java.util.Arrays; 59 import java.util.Arrays;
  60 +import java.util.Collection;
62 import java.util.Date; 61 import java.util.Date;
63 import java.util.Set; 62 import java.util.Set;
64 import java.util.concurrent.ExecutorService; 63 import java.util.concurrent.ExecutorService;
@@ -111,7 +110,7 @@ public class LwM2mTransportRequest { @@ -111,7 +110,7 @@ public class LwM2mTransportRequest {
111 * @param typeOper - 110 * @param typeOper -
112 * @param contentFormatName - 111 * @param contentFormatName -
113 */ 112 */
114 - @SneakyThrows 113 +
115 public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, 114 public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper,
116 String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { 115 String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) {
117 try { 116 try {
@@ -160,8 +159,7 @@ public class LwM2mTransportRequest { @@ -160,8 +159,7 @@ public class LwM2mTransportRequest {
160 break; 159 break;
161 case WRITE_REPLACE: 160 case WRITE_REPLACE:
162 // Request to write a <b>String Single-Instance Resource</b> using the TLV content format. 161 // Request to write a <b>String Single-Instance Resource</b> using the TLV content format.
163 - resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config  
164 - .getModelProvider()); 162 + resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
165 if (contentFormat.equals(ContentFormat.TLV)) { 163 if (contentFormat.equals(ContentFormat.TLV)) {
166 request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(), 164 request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(),
167 resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type, 165 resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type,
@@ -175,15 +173,31 @@ public class LwM2mTransportRequest { @@ -175,15 +173,31 @@ public class LwM2mTransportRequest {
175 } 173 }
176 break; 174 break;
177 case WRITE_UPDATE: 175 case WRITE_UPDATE:
178 -// LwM2mNode node = null;  
179 -// if (resultIds.isObjectInstance()) {  
180 -// node = new LwM2mObjectInstance(resultIds.getObjectInstanceId(), lwM2MClient.  
181 -// getNewResourcesForInstance(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider(),  
182 -// this.converter));  
183 -// request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, target, node);  
184 -// } else if (resultIds.getObjectId() >= 0) {  
185 -// request = new ObserveRequest(resultIds.getObjectId());  
186 -// } 176 + if (resultIds.isResource()) {
  177 + /**
  178 + * send request: path = '/3/0' node == wM2mObjectInstance
  179 + * with params == "\"resources\": {15: resource:{id:15. value:'+01'...}}
  180 + **/
  181 + Collection<LwM2mResource> resources = lwM2MClient.getNewResourcesForInstance(
  182 + targetIdVer, params,
  183 + this.config.getModelProvider(),
  184 + this.converter);
  185 + request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
  186 + resultIds.getObjectInstanceId(), resources);
  187 + }
  188 +
  189 + /**
  190 + * params = "{\"id\":0,\"resources\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}"
  191 + *
  192 + * int rscId = resultIds.getObjectInstanceId();
  193 + */
  194 +
  195 + else if (resultIds.isObjectInstance()) {
  196 + String content = (String) params;
  197 +// node = Gson.fromJson((content, LwM2mNode.class);
  198 + } else if (resultIds.getObjectId() >= 0) {
  199 + request = new ObserveRequest(resultIds.getObjectId());
  200 + }
187 break; 201 break;
188 case WRITE_ATTRIBUTES: 202 case WRITE_ATTRIBUTES:
189 request = createWriteAttributeRequest(target, params); 203 request = createWriteAttributeRequest(target, params);
@@ -236,7 +250,11 @@ public class LwM2mTransportRequest { @@ -236,7 +250,11 @@ public class LwM2mTransportRequest {
236 String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, 250 String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR,
237 typeOper.name(), e.getMessage()); 251 typeOper.name(), e.getMessage());
238 serviceImpl.sendLogsToThingsboard(msg, registration.getId()); 252 serviceImpl.sendLogsToThingsboard(msg, registration.getId());
239 - throw new Exception(e); 253 + try {
  254 + throw new Exception(e);
  255 + } catch (Exception exception) {
  256 + exception.printStackTrace();
  257 + }
240 } 258 }
241 } 259 }
242 260
@@ -248,6 +266,7 @@ public class LwM2mTransportRequest { @@ -248,6 +266,7 @@ public class LwM2mTransportRequest {
248 266
249 @SuppressWarnings("unchecked") 267 @SuppressWarnings("unchecked")
250 private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { 268 private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) {
  269 +
251 context.getServer().send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { 270 context.getServer().send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
252 if (!lwM2MClient.isInit()) { 271 if (!lwM2MClient.isInit()) {
253 lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); 272 lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration));
@@ -117,9 +117,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { @@ -117,9 +117,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
117 117
118 private ObjectModel getObjectModelDynamic(Integer objectId, String version) { 118 private ObjectModel getObjectModelDynamic(Integer objectId, String version) {
119 String key = getKeyIdVer(objectId, version); 119 String key = getKeyIdVer(objectId, version);
120 -  
121 Optional<TbResource> tbResource = context.getTransportResourceCache().get(this.tenantId, LWM2M_MODEL, key); 120 Optional<TbResource> tbResource = context.getTransportResourceCache().get(this.tenantId, LWM2M_MODEL, key);
122 -  
123 return tbResource.map(resource -> helper.parseFromXmlToObjectModel( 121 return tbResource.map(resource -> helper.parseFromXmlToObjectModel(
124 Base64.getDecoder().decode(resource.getData()), 122 Base64.getDecoder().decode(resource.getData()),
125 key + ".xml", 123 key + ".xml",
@@ -26,8 +26,8 @@ import org.eclipse.leshan.server.registration.Registration; @@ -26,8 +26,8 @@ import org.eclipse.leshan.server.registration.Registration;
26 import org.eclipse.leshan.server.security.SecurityInfo; 26 import org.eclipse.leshan.server.security.SecurityInfo;
27 import org.thingsboard.server.gen.transport.TransportProtos; 27 import org.thingsboard.server.gen.transport.TransportProtos;
28 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
29 -import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;  
30 import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; 29 import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
  30 +import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
31 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 31 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
32 32
33 import java.util.Collection; 33 import java.util.Collection;
@@ -111,15 +111,17 @@ public class LwM2mClient implements Cloneable { @@ -111,15 +111,17 @@ public class LwM2mClient implements Cloneable {
111 .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null; 111 .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null;
112 } 112 }
113 113
114 - public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, LwM2mModelProvider modelProvider, 114 + public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
115 LwM2mValueConverterImpl converter) { 115 LwM2mValueConverterImpl converter) {
116 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer)); 116 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer));
117 Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet(); 117 Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet();
118 Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration) 118 Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration)
119 .getObjectModel(pathIds.getObjectId()).resources; 119 .getObjectModel(pathIds.getObjectId()).resources;
120 - resourceModels.forEach((k, resourceModel) -> {  
121 - resources.add(LwM2mSingleResource.newResource(k, converter.convertValue("0", ResourceModel.Type.STRING, resourceModel.type, pathIds), resourceModel.type));  
122 - }); 120 + resourceModels.forEach((resId, resourceModel) -> {
  121 + if (resId == pathIds.getResourceId()) {
  122 + resources.add(LwM2mSingleResource.newResource(resId, converter.convertValue(params, ResourceModel.Type.STRING, resourceModel.type, pathIds), resourceModel.type));
  123 +
  124 + }});
123 return resources; 125 return resources;
124 } 126 }
125 127
@@ -60,11 +60,14 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { @@ -60,11 +60,14 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
60 case INTEGER: 60 case INTEGER:
61 switch (currentType) { 61 switch (currentType) {
62 case FLOAT: 62 case FLOAT:
63 - log.debug("Trying to convert float value [{}] to integer", value); 63 + log.debug("Trying to convert float value [{}] to Integer", value);
64 Long longValue = ((Double) value).longValue(); 64 Long longValue = ((Double) value).longValue();
65 if ((double) value == longValue.doubleValue()) { 65 if ((double) value == longValue.doubleValue()) {
66 return longValue; 66 return longValue;
67 } 67 }
  68 + case STRING:
  69 + log.debug("Trying to convert String value [{}] to Integer", value);
  70 + return Long.parseLong((String) value);
68 default: 71 default:
69 break; 72 break;
70 } 73 }
@@ -77,6 +80,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { @@ -77,6 +80,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
77 if ((long) value == floatValue.longValue()) { 80 if ((long) value == floatValue.longValue()) {
78 return floatValue; 81 return floatValue;
79 } 82 }
  83 + case STRING:
  84 + log.debug("Trying to convert String value [{}] to Float", value);
  85 + return Float.valueOf((String) value);
80 default: 86 default:
81 break; 87 break;
82 } 88 }