|
|
|
@ -19,7 +19,6 @@ import com.google.gson.Gson; |
|
|
|
import com.google.gson.GsonBuilder; |
|
|
|
import com.google.gson.JsonElement; |
|
|
|
import com.google.gson.JsonObject; |
|
|
|
import com.google.gson.reflect.TypeToken; |
|
|
|
import jakarta.annotation.PostConstruct; |
|
|
|
import jakarta.annotation.PreDestroy; |
|
|
|
import lombok.Getter; |
|
|
|
@ -60,6 +59,7 @@ import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTrans |
|
|
|
import org.thingsboard.server.common.data.device.profile.lwm2m.ObjectAttributes; |
|
|
|
import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; |
|
|
|
import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; |
|
|
|
import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryObserveStrategy; |
|
|
|
import org.thingsboard.server.common.data.id.DeviceId; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.data.ota.OtaPackageUtil; |
|
|
|
@ -78,7 +78,7 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientState; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.ParametersAnalyzeResult; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.ResourceUpdateResult; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.common.LwM2MExecutorAwareService; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.DownlinkRequestCallback; |
|
|
|
@ -92,9 +92,14 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadCallbac |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequest; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesCallback; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.composite.TbLwM2MObserveCompositeCallback; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.downlink.composite.TbLwM2MObserveCompositeRequest; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.model.LwM2MModelConfig; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.model.LwM2MModelConfigService; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.model.ParametersAnalyzeResult; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.model.ParametersObserveAnalyzeResult; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.model.ParametersUpdateAnalyzeResult; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.session.LwM2MSessionManager; |
|
|
|
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
|
|
|
@ -109,6 +114,7 @@ import java.util.Collections; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.Optional; |
|
|
|
import java.util.Random; |
|
|
|
import java.util.Set; |
|
|
|
@ -116,9 +122,10 @@ import java.util.UUID; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.concurrent.atomic.AtomicLong; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import static org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryObserveStrategy.COMPOSITE_BY_OBJECT; |
|
|
|
import static org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryObserveStrategy.SINGLE; |
|
|
|
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
|
|
|
import static org.thingsboard.server.common.data.util.CollectionsUtil.diffSets; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_3_VER_ID; |
|
|
|
@ -135,9 +142,11 @@ import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaU |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_ERROR; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_INFO; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_WARN; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.areArraysStringEqual; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertObjectIdToVersionedId; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertOtaUpdateValueToString; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.groupByObjectIdVersionedIds; |
|
|
|
|
|
|
|
|
|
|
|
@Slf4j |
|
|
|
@ -314,40 +323,41 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); |
|
|
|
ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, modelProvider); |
|
|
|
if (objectModelVersion != null) { |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
int responseCode = response.getCode().getCode(); |
|
|
|
if (content instanceof LwM2mObject) { |
|
|
|
LwM2mObject lwM2mObject = (LwM2mObject) content; |
|
|
|
this.updateObjectResourceValue(lwM2MClient, lwM2mObject, path, responseCode); |
|
|
|
this.updateObjectResourceValue(updateResource, (LwM2mObject) content, path, responseCode); |
|
|
|
} else if (content instanceof LwM2mObjectInstance) { |
|
|
|
LwM2mObjectInstance lwM2mObjectInstance = (LwM2mObjectInstance) content; |
|
|
|
this.updateObjectInstanceResourceValue(lwM2MClient, lwM2mObjectInstance, path, responseCode); |
|
|
|
this.updateObjectInstanceResourceValue(updateResource, (LwM2mObjectInstance) content, path, responseCode); |
|
|
|
} else if (content instanceof LwM2mResource) { |
|
|
|
LwM2mResource lwM2mResource = (LwM2mResource) content; |
|
|
|
this.updateResourcesValue(lwM2MClient, lwM2mResource, path, Mode.UPDATE, responseCode); |
|
|
|
this.updateResourcesValue(updateResource, (LwM2mResource) content, path, Mode.UPDATE, responseCode); |
|
|
|
} |
|
|
|
this.updateAttrTelemetry(updateResource, null); |
|
|
|
} |
|
|
|
tryAwake(lwM2MClient); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void onUpdateValueAfterReadCompositeResponse(Registration registration, ReadCompositeResponse response) { |
|
|
|
log.trace("ReadCompositeResponse: [{}]", response); |
|
|
|
log.trace("ReadCompositeResponse before onUpdateValueAfterReadCompositeResponse: [{}]", response); |
|
|
|
if (response.getContent() != null) { |
|
|
|
LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
response.getContent().forEach((k, v) -> { |
|
|
|
if (v != null) { |
|
|
|
int responseCode = response.getCode().getCode(); |
|
|
|
if (v instanceof LwM2mObject) { |
|
|
|
this.updateObjectResourceValue(lwM2MClient, (LwM2mObject) v, k.toString(), responseCode); |
|
|
|
this.updateObjectResourceValue(updateResource, (LwM2mObject) v, k.toString(), responseCode); |
|
|
|
} else if (v instanceof LwM2mObjectInstance) { |
|
|
|
this.updateObjectInstanceResourceValue(lwM2MClient, (LwM2mObjectInstance) v, k.toString(), responseCode); |
|
|
|
this.updateObjectInstanceResourceValue(updateResource, (LwM2mObjectInstance) v, k.toString(), responseCode); |
|
|
|
} else if (v instanceof LwM2mResource) { |
|
|
|
this.updateResourcesValue(lwM2MClient, (LwM2mResource) v, k.toString(), Mode.UPDATE, responseCode); |
|
|
|
this.updateResourcesValue(updateResource, (LwM2mResource) v, k.toString(), Mode.UPDATE, responseCode); |
|
|
|
} |
|
|
|
} else { |
|
|
|
this.onErrorObservation(registration, k + ": value in composite response is null"); |
|
|
|
} |
|
|
|
}); |
|
|
|
this.updateAttrTelemetry(updateResource, null); |
|
|
|
clientContext.update(lwM2MClient); |
|
|
|
tryAwake(lwM2MClient); |
|
|
|
} |
|
|
|
@ -375,16 +385,15 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); |
|
|
|
ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path.toString(), modelProvider); |
|
|
|
if (objectModelVersion != null) { |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
if (node instanceof LwM2mObject) { |
|
|
|
LwM2mObject lwM2mObject = (LwM2mObject) node; |
|
|
|
this.updateObjectResourceValue(lwM2MClient, lwM2mObject, path.toString(), 0); |
|
|
|
this.updateObjectResourceValue(updateResource, (LwM2mObject) node, path.toString(), 0); |
|
|
|
} else if (node instanceof LwM2mObjectInstance) { |
|
|
|
LwM2mObjectInstance lwM2mObjectInstance = (LwM2mObjectInstance) node; |
|
|
|
this.updateObjectInstanceResourceValue(lwM2MClient, lwM2mObjectInstance, path.toString(), 0); |
|
|
|
this.updateObjectInstanceResourceValue(updateResource, (LwM2mObjectInstance) node, path.toString(), 0); |
|
|
|
} else if (node instanceof LwM2mResource) { |
|
|
|
LwM2mResource lwM2mResource = (LwM2mResource) node; |
|
|
|
this.updateResourcesValueWithTs(lwM2MClient, lwM2mResource, path.toString(), Mode.UPDATE, ts); |
|
|
|
this.updateResourcesValue(updateResource, (LwM2mResource) node, path.toString(), Mode.UPDATE, 0); |
|
|
|
} |
|
|
|
this.updateAttrTelemetry(updateResource, ts); |
|
|
|
} |
|
|
|
tryAwake(lwM2MClient); |
|
|
|
} |
|
|
|
@ -398,14 +407,15 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
@Override |
|
|
|
public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { |
|
|
|
try { |
|
|
|
|
|
|
|
List<LwM2mClient> clients = clientContext.getLwM2mClients() |
|
|
|
.stream().filter(e -> e.getProfileId() != null) |
|
|
|
.filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toList()); |
|
|
|
clients.forEach(client -> { |
|
|
|
client.onDeviceProfileUpdate(deviceProfile); |
|
|
|
}); |
|
|
|
if (clients.size() > 0) { |
|
|
|
var oldProfile = clientContext.getProfile(deviceProfile.getUuidId()); |
|
|
|
if (!clients.isEmpty()) { |
|
|
|
var oldProfile = clientContext.getProfile(clients.get(0).getRegistration()); |
|
|
|
this.onDeviceProfileUpdate(clients, oldProfile, deviceProfile); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
@ -471,11 +481,11 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
* @param lwM2MClient - object with All parameters off client |
|
|
|
*/ |
|
|
|
private void initClientTelemetry(LwM2mClient lwM2MClient) { |
|
|
|
Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); |
|
|
|
Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getRegistration()); |
|
|
|
Set<String> supportedObjects = clientContext.getSupportedIdVerInClient(lwM2MClient); |
|
|
|
if (supportedObjects != null && supportedObjects.size() > 0) { |
|
|
|
this.sendReadRequests(lwM2MClient, profile, supportedObjects); |
|
|
|
this.sendObserveRequests(lwM2MClient, profile, supportedObjects); |
|
|
|
this.sendInitObserveRequests(lwM2MClient, profile, supportedObjects); |
|
|
|
this.sendWriteAttributeRequests(lwM2MClient, profile, supportedObjects); |
|
|
|
// Removed. Used only for debug.
|
|
|
|
// this.sendDiscoverRequests(lwM2MClient, profile, supportedObjects);
|
|
|
|
@ -501,16 +511,38 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void sendObserveRequests(LwM2mClient lwM2MClient, Lwm2mDeviceProfileTransportConfiguration profile, Set<String> supportedObjects) { |
|
|
|
private void sendInitObserveRequests(LwM2mClient lwM2MClient, Lwm2mDeviceProfileTransportConfiguration profile, Set<String> supportedObjects) { |
|
|
|
try { |
|
|
|
Set<String> targetIds = profile.getObserveAttr().getObserve(); |
|
|
|
targetIds = targetIds.stream().filter(target -> isSupportedTargetId(supportedObjects, target)).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
CountDownLatch latch = new CountDownLatch(targetIds.size()); |
|
|
|
targetIds.forEach(targetId -> sendObserveRequest(lwM2MClient, targetId, |
|
|
|
new TbLwM2MLatchCallback<>(latch, new TbLwM2MObserveCallback(this, logService, lwM2MClient, targetId)))); |
|
|
|
|
|
|
|
latch.await(config.getTimeout(), TimeUnit.MILLISECONDS); |
|
|
|
if (!targetIds.isEmpty()) { |
|
|
|
TelemetryObserveStrategy observeStrategy = profile.getObserveAttr().getObserveStrategy(); |
|
|
|
long timeoutMs = config.getTimeout(); |
|
|
|
switch (observeStrategy) { |
|
|
|
case SINGLE -> { |
|
|
|
CountDownLatch latch = new CountDownLatch(targetIds.size()); |
|
|
|
targetIds.forEach(targetId -> sendObserveRequest( |
|
|
|
lwM2MClient, targetId, |
|
|
|
new TbLwM2MLatchCallback<>(latch, new TbLwM2MObserveCallback(this, logService, lwM2MClient, targetId)) |
|
|
|
)); |
|
|
|
boolean completed = latch.await(timeoutMs, TimeUnit.MILLISECONDS); |
|
|
|
if (!completed) log.trace("[{}] Timeout occurred during SINGLE observe init", lwM2MClient.getEndpoint()); |
|
|
|
} |
|
|
|
case COMPOSITE_ALL -> { |
|
|
|
CountDownLatch latch = new CountDownLatch(targetIds.size()); |
|
|
|
sendObserveCompositeRequest(lwM2MClient, targetIds.toArray(new String[0])); |
|
|
|
boolean completed = latch.await(timeoutMs, TimeUnit.MILLISECONDS); |
|
|
|
if (!completed) log.trace("[{}] Timeout occurred during COMPOSITE_ALL observe init", lwM2MClient.getEndpoint()); |
|
|
|
} |
|
|
|
case COMPOSITE_BY_OBJECT -> { |
|
|
|
Map<Integer, String[]> versionedObjectIds = groupByObjectIdVersionedIds(targetIds); |
|
|
|
CountDownLatch latch = new CountDownLatch(versionedObjectIds.size()); |
|
|
|
versionedObjectIds.forEach((k, v) -> sendObserveCompositeRequest(lwM2MClient, v)); |
|
|
|
boolean completed = latch.await(timeoutMs, TimeUnit.MILLISECONDS); |
|
|
|
if (!completed) log.trace("[{}] Timeout occurred during COMPOSITE_BY_OBJECT observe init", lwM2MClient.getEndpoint()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (InterruptedException e) { |
|
|
|
log.error("[{}] Failed to await Observe requests!", lwM2MClient.getEndpoint(), e); |
|
|
|
} catch (Exception e) { |
|
|
|
@ -547,6 +579,12 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
TbLwM2MObserveRequest request = TbLwM2MObserveRequest.builder().versionedId(versionedId).timeout(clientContext.getRequestTimeout(lwM2MClient)).build(); |
|
|
|
defaultLwM2MDownlinkMsgHandler.sendObserveRequest(lwM2MClient, request, callback); |
|
|
|
} |
|
|
|
private void sendObserveCompositeRequest(LwM2mClient lwM2MClient, String[] versionedIds) { |
|
|
|
|
|
|
|
TbLwM2MObserveCompositeRequest request = TbLwM2MObserveCompositeRequest.builder().versionedIds(versionedIds).timeout(clientContext.getRequestTimeout(lwM2MClient)).build(); |
|
|
|
var mainCallback = new TbLwM2MObserveCompositeCallback(this, logService, lwM2MClient, versionedIds); |
|
|
|
defaultLwM2MDownlinkMsgHandler.sendObserveCompositeRequest(lwM2MClient, request, mainCallback); |
|
|
|
} |
|
|
|
|
|
|
|
private void sendWriteAttributesRequest(LwM2mClient lwM2MClient, String targetId, ObjectAttributes params) { |
|
|
|
TbLwM2MWriteAttributesRequest request = TbLwM2MWriteAttributesRequest.builder().versionedId(targetId).attributes(params).timeout(clientContext.getRequestTimeout(lwM2MClient)).build(); |
|
|
|
@ -558,18 +596,18 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
defaultLwM2MDownlinkMsgHandler.sendCancelObserveRequest(client, request, new TbLwM2MCancelObserveCallback(logService, client, versionedId)); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateObjectResourceValue(LwM2mClient client, LwM2mObject lwM2mObject, String pathIdVer, int code) { |
|
|
|
private void updateObjectResourceValue(ResourceUpdateResult updateResource, LwM2mObject lwM2mObject, String pathIdVer, int code) { |
|
|
|
LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)); |
|
|
|
lwM2mObject.getInstances().forEach((instanceId, instance) -> { |
|
|
|
String pathInstance = pathIds.toString() + "/" + instanceId; |
|
|
|
this.updateObjectInstanceResourceValue(client, instance, pathInstance, code); |
|
|
|
this.updateObjectInstanceResourceValue(updateResource, instance, pathInstance, code); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateObjectInstanceResourceValue(LwM2mClient client, LwM2mObjectInstance lwM2mObjectInstance, String pathIdVer, int code) { |
|
|
|
private void updateObjectInstanceResourceValue(ResourceUpdateResult updateResource, LwM2mObjectInstance lwM2mObjectInstance, String pathIdVer, int code) { |
|
|
|
lwM2mObjectInstance.getResources().forEach((resourceId, resource) -> { |
|
|
|
String pathRez = pathIdVer + "/" + resourceId; |
|
|
|
this.updateResourcesValue(client, resource, pathRez, Mode.UPDATE, code); |
|
|
|
this.updateResourcesValue(updateResource, resource, pathRez, Mode.UPDATE, code); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@ -579,56 +617,50 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
* #2 Update new Resources (replace old Resource Value on new Resource Value) |
|
|
|
* #3 If fr_update -> UpdateFirmware |
|
|
|
* #4 updateAttrTelemetry |
|
|
|
* @param lwM2MClient - Registration LwM2M Client |
|
|
|
* @param updateResource - result update resource by LwM2M Client |
|
|
|
* @param lwM2mResource - LwM2mSingleResource response.getContent() |
|
|
|
* @param stringPath - resource |
|
|
|
* @param mode - Replace, Update |
|
|
|
*/ |
|
|
|
private void updateResourcesValue(LwM2mClient lwM2MClient, LwM2mResource lwM2mResource, String stringPath, Mode mode, int code) { |
|
|
|
Registration registration = lwM2MClient.getRegistration(); |
|
|
|
private void updateResourcesValue(ResourceUpdateResult updateResource, LwM2mResource lwM2mResource, String stringPath, Mode mode, int code) { |
|
|
|
LwM2mClient lwM2MClient = updateResource.getLwM2MClient(); |
|
|
|
String path = convertObjectIdToVersionedId(stringPath, lwM2MClient); |
|
|
|
if (lwM2MClient.saveResourceValue(path, lwM2mResource, modelProvider, mode)) { |
|
|
|
if (path.equals(convertObjectIdToVersionedId(FW_NAME_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_3_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_STATE_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_RESULT_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_DELIVERY_METHOD, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareDeliveryMethodUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_NAME_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_3_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_STATE_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_RESULT_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} |
|
|
|
if (path != null && lwM2MClient.saveResourceValue(path, lwM2mResource, modelProvider, mode)) { |
|
|
|
this.updateOtaResource(lwM2MClient, lwM2mResource, path); |
|
|
|
if (ResponseCode.BAD_REQUEST.getCode() > code) { |
|
|
|
this.updateAttrTelemetry(registration, path, null); |
|
|
|
updateResource.getPaths().add(path); |
|
|
|
} |
|
|
|
} else { |
|
|
|
log.error("Fail update path [{}] Resource [{}]", path, lwM2mResource); |
|
|
|
} |
|
|
|
} |
|
|
|
private void updateResourcesValueWithTs(LwM2mClient lwM2MClient, LwM2mResource lwM2mResource, String stringPath, Mode mode, Instant ts) { |
|
|
|
Registration registration = lwM2MClient.getRegistration(); |
|
|
|
String path = convertObjectIdToVersionedId(stringPath, lwM2MClient); |
|
|
|
if (lwM2MClient.saveResourceValue(path, lwM2mResource, modelProvider, mode)) { |
|
|
|
this.updateAttrTelemetry(registration, path, ts); |
|
|
|
} else { |
|
|
|
log.error("Fail update path [{}] Resource [{}] with ts.", path, lwM2mResource); |
|
|
|
|
|
|
|
private void updateOtaResource(LwM2mClient lwM2MClient, LwM2mResource lwM2mResource, String path) { |
|
|
|
if (path.equals(convertObjectIdToVersionedId(FW_NAME_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_3_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_STATE_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_RESULT_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(FW_DELIVERY_METHOD, lwM2MClient))) { |
|
|
|
otaService.onCurrentFirmwareDeliveryMethodUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_NAME_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_3_VER_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_STATE_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} else if (path.equals(convertObjectIdToVersionedId(SW_RESULT_ID, lwM2MClient))) { |
|
|
|
otaService.onCurrentSoftwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* send Attribute and Telemetry to Thingsboard |
|
|
|
* #1 - get AttrName/TelemetryName with value from LwM2MClient: |
|
|
|
@ -636,20 +668,20 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
* -- AttrName/TelemetryName == resourceName from ModelObject.objectModel, value from ModelObject.instance.resource(resourceId) |
|
|
|
* #2 - set Attribute/Telemetry |
|
|
|
* |
|
|
|
* @param registration - Registration LwM2M Client |
|
|
|
* @param updateResource - updateResource resource of LwM2M Client |
|
|
|
*/ |
|
|
|
public void updateAttrTelemetry(Registration registration, String path, Instant ts) { |
|
|
|
log.trace("UpdateAttrTelemetry paths [{}]", path); |
|
|
|
public void updateAttrTelemetry(ResourceUpdateResult updateResource, Instant ts) { |
|
|
|
log.trace("UpdateAttrTelemetry paths [{}]", updateResource.getPaths()); |
|
|
|
try { |
|
|
|
ResultsAddKeyValueProto results = this.getParametersFromProfile(registration, path); |
|
|
|
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); |
|
|
|
ResultsAddKeyValueProto results = this.getParametersFromProfile(updateResource); |
|
|
|
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(updateResource.getLwM2MClient().getRegistration()); |
|
|
|
if (results != null && sessionInfo != null) { |
|
|
|
if (results.getResultAttributes().size() > 0) { |
|
|
|
log.trace("UpdateAttribute paths [{}] value [{}]", path, results.getResultAttributes().get(0).toString()); |
|
|
|
log.trace("UpdateAttribute paths [{}] value [{}]", updateResource.getPaths(), results.getResultAttributes().get(0).toString()); |
|
|
|
this.helper.sendParametersOnThingsboardAttribute(results.getResultAttributes(), sessionInfo); |
|
|
|
} |
|
|
|
if (results.getResultTelemetries().size() > 0) { |
|
|
|
log.trace("UpdateTelemetry paths [{}] value [{}] ts [{}]", path, results.getResultTelemetries().get(0).toString(), ts == null ? "null" : ts.toEpochMilli()); |
|
|
|
log.trace("UpdateTelemetry paths [{}] value [{}] ts [{}]", updateResource.getPaths(), results.getResultTelemetries().get(0).toString(), ts == null ? "null" : ts.toEpochMilli()); |
|
|
|
this.helper.sendParametersOnThingsboardTelemetry(results.getResultTelemetries(), sessionInfo, null, ts); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -673,15 +705,8 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
private ConcurrentHashMap<String, Object> getPathForWriteAttributes(JsonObject objectJson) { |
|
|
|
ConcurrentHashMap<String, Object> pathAttributes = new Gson().fromJson(objectJson.toString(), |
|
|
|
new TypeToken<ConcurrentHashMap<String, Object>>() { |
|
|
|
}.getType()); |
|
|
|
return pathAttributes; |
|
|
|
} |
|
|
|
|
|
|
|
private void onDeviceUpdate(LwM2mClient lwM2MClient, Device device, Optional<DeviceProfile> deviceProfileOpt) { |
|
|
|
var oldProfile = clientContext.getProfile(lwM2MClient.getProfileId()); |
|
|
|
var oldProfile = clientContext.getProfile(lwM2MClient.getRegistration()); |
|
|
|
deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceProfileUpdate(Collections.singletonList(lwM2MClient), oldProfile, deviceProfile)); |
|
|
|
lwM2MClient.onDeviceUpdate(device, deviceProfileOpt); |
|
|
|
} |
|
|
|
@ -690,31 +715,68 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
* // * @param attributes - new JsonObject
|
|
|
|
* // * @param telemetry - new JsonObject
|
|
|
|
* |
|
|
|
* @param registration - Registration LwM2M Client |
|
|
|
* @param path - |
|
|
|
* @param updateResource - updateResource resource of LwM2M Client |
|
|
|
*/ |
|
|
|
private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, String path) { |
|
|
|
private ResultsAddKeyValueProto getParametersFromProfile(ResourceUpdateResult updateResource) { |
|
|
|
Registration registration = updateResource.getLwM2MClient().getRegistration(); |
|
|
|
Set<String> paths = updateResource.getPaths(); |
|
|
|
ResultsAddKeyValueProto results = new ResultsAddKeyValueProto(); |
|
|
|
var profile = clientContext.getProfile(registration); |
|
|
|
List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>(); |
|
|
|
Set<String> attributes = profile.getObserveAttr().getAttribute().stream() |
|
|
|
.filter(paths::contains) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
if (!attributes.isEmpty()){ |
|
|
|
attributes.stream() |
|
|
|
.map(attr -> this.getKvToThingsBoard(attr, registration)) |
|
|
|
.filter(Objects::nonNull) |
|
|
|
.forEach(resultAttributes::add); |
|
|
|
} |
|
|
|
List<TransportProtos.KeyValueProto> resultTelemetries = new ArrayList<>(); |
|
|
|
Set<String> telemetries = profile.getObserveAttr().getTelemetry().stream() |
|
|
|
.filter(paths::contains) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
if (!telemetries.isEmpty()){ |
|
|
|
telemetries.stream() |
|
|
|
.map(telemetry -> this.getKvToThingsBoard(telemetry, registration)) |
|
|
|
.filter(Objects::nonNull) |
|
|
|
.forEach(resultTelemetries::add); |
|
|
|
} |
|
|
|
if (resultAttributes.size() > 0) { |
|
|
|
results.setResultAttributes(resultAttributes); |
|
|
|
} |
|
|
|
if (resultTelemetries.size() > 0) { |
|
|
|
results.setResultTelemetries(resultTelemetries); |
|
|
|
} |
|
|
|
return results; |
|
|
|
} |
|
|
|
|
|
|
|
private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, Set<String> path) { |
|
|
|
if (!path.isEmpty()) { |
|
|
|
ResultsAddKeyValueProto results = new ResultsAddKeyValueProto(); |
|
|
|
var profile = clientContext.getProfile(registration); |
|
|
|
List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>(); |
|
|
|
profile.getObserveAttr().getAttribute().forEach(pathIdVer -> { |
|
|
|
if (path.equals(pathIdVer)) { |
|
|
|
TransportProtos.KeyValueProto kvAttr = this.getKvToThingsBoard(pathIdVer, registration); |
|
|
|
if (kvAttr != null) { |
|
|
|
resultAttributes.add(kvAttr); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
Set<String> attributes = profile.getObserveAttr().getAttribute().stream() |
|
|
|
.map(LwM2MTransportUtil::fromVersionedIdToObjectId) |
|
|
|
.filter(path::contains) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
if (!attributes.isEmpty()){ |
|
|
|
attributes.stream() |
|
|
|
.map(attr -> this.getKvToThingsBoard(attr, registration)) |
|
|
|
.filter(Objects::nonNull) |
|
|
|
.forEach(resultAttributes::add); |
|
|
|
} |
|
|
|
List<TransportProtos.KeyValueProto> resultTelemetries = new ArrayList<>(); |
|
|
|
profile.getObserveAttr().getTelemetry().forEach(pathIdVer -> { |
|
|
|
if (path.contains(pathIdVer)) { |
|
|
|
TransportProtos.KeyValueProto kvAttr = this.getKvToThingsBoard(pathIdVer, registration); |
|
|
|
if (kvAttr != null) { |
|
|
|
resultTelemetries.add(kvAttr); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
Set<String> telemetries = profile.getObserveAttr().getTelemetry().stream() |
|
|
|
.map(LwM2MTransportUtil::fromVersionedIdToObjectId) |
|
|
|
.filter(path::contains) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
if (!telemetries.isEmpty()){ |
|
|
|
telemetries.stream() |
|
|
|
.map(telemetry -> this.getKvToThingsBoard(telemetry, registration)) |
|
|
|
.filter(Objects::nonNull) |
|
|
|
.forEach(resultTelemetries::add); |
|
|
|
} |
|
|
|
if (resultAttributes.size() > 0) { |
|
|
|
results.setResultAttributes(resultAttributes); |
|
|
|
} |
|
|
|
@ -728,7 +790,7 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
|
|
|
|
private TransportProtos.KeyValueProto getKvToThingsBoard(String pathIdVer, Registration registration) { |
|
|
|
LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); |
|
|
|
Map<String, String> names = clientContext.getProfile(lwM2MClient.getProfileId()).getObserveAttr().getKeyName(); |
|
|
|
Map<String, String> names = clientContext.getProfile(lwM2MClient.getRegistration()).getObserveAttr().getKeyName(); |
|
|
|
if (names != null && names.containsKey(pathIdVer)) { |
|
|
|
String resourceName = names.get(pathIdVer); |
|
|
|
if (resourceName != null && !resourceName.isEmpty()) { |
|
|
|
@ -770,117 +832,94 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onWriteResponseOk(LwM2mClient client, String path, WriteRequest request, int code) { |
|
|
|
public void onWriteResponseOk(LwM2mClient lwM2MClient, String path, WriteRequest request, int code) { |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
if (request.getNode() instanceof LwM2mResource) { |
|
|
|
this.updateResourcesValue(client, ((LwM2mResource) request.getNode()), path, request.isReplaceRequest() ? Mode.REPLACE : Mode.UPDATE, code); |
|
|
|
this.updateResourcesValue(updateResource, ((LwM2mResource) request.getNode()), path, request.isReplaceRequest() ? Mode.REPLACE : Mode.UPDATE, code); |
|
|
|
} else if (request.getNode() instanceof LwM2mObjectInstance) { |
|
|
|
((LwM2mObjectInstance) request.getNode()).getResources().forEach((resId, resource) -> { |
|
|
|
this.updateResourcesValue(client, resource, path + "/" + resId, request.isReplaceRequest() ? Mode.REPLACE : Mode.UPDATE, code); |
|
|
|
this.updateResourcesValue(updateResource, resource, path + "/" + resId, request.isReplaceRequest() ? Mode.REPLACE : Mode.UPDATE, code); |
|
|
|
}); |
|
|
|
} |
|
|
|
if (request.getNode() instanceof LwM2mResource || request.getNode() instanceof LwM2mObjectInstance) { |
|
|
|
clientContext.update(client); |
|
|
|
clientContext.update(lwM2MClient); |
|
|
|
} |
|
|
|
this.updateAttrTelemetry(updateResource, null); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onCreateResponseOk(LwM2mClient client, String path, CreateRequest request) { |
|
|
|
if (request.getObjectInstances() != null && request.getObjectInstances().size() > 0) { |
|
|
|
public void onCreatebjectInstancesResponseOk(LwM2mClient lwM2MClient, String versionId, CreateRequest request) { |
|
|
|
if (request.getObjectInstances() != null && !request.getObjectInstances().isEmpty()) { |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
request.getObjectInstances().forEach(instance -> |
|
|
|
instance.getResources() |
|
|
|
instance.getResources().forEach((resId, lwM2mResource) ->{ |
|
|
|
this.updateResourcesValue(updateResource, lwM2mResource, versionId + "/" + resId, Mode.REPLACE, 0); |
|
|
|
}) |
|
|
|
); |
|
|
|
clientContext.update(client); |
|
|
|
clientContext.update(lwM2MClient); |
|
|
|
this.updateAttrTelemetry(updateResource, null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onWriteCompositeResponseOk(LwM2mClient client, WriteCompositeRequest request, int code) { |
|
|
|
public void onWriteCompositeResponseOk(LwM2mClient lwM2MClient, WriteCompositeRequest request, int code) { |
|
|
|
log.trace("ReadCompositeResponse: [{}]", request.getNodes()); |
|
|
|
ResourceUpdateResult updateResource = new ResourceUpdateResult(lwM2MClient); |
|
|
|
request.getNodes().forEach((k, v) -> { |
|
|
|
if (v instanceof LwM2mSingleResource) { |
|
|
|
this.updateResourcesValue(client, (LwM2mResource) v, k.toString(), Mode.REPLACE, code); |
|
|
|
this.updateResourcesValue(updateResource, (LwM2mResource) v, k.toString(), Mode.REPLACE, code); |
|
|
|
} else { |
|
|
|
LwM2mResourceInstance resourceInstance = (LwM2mResourceInstance) v; |
|
|
|
LwM2mMultipleResource multipleResource = new LwM2mMultipleResource(((LwM2mResourceInstance) v).getId(), resourceInstance.getType(), resourceInstance); |
|
|
|
this.updateResourcesValue(client, multipleResource, k.toString(), Mode.REPLACE, code); |
|
|
|
this.updateResourcesValue(updateResource, multipleResource, k.toString(), Mode.REPLACE, code); |
|
|
|
} |
|
|
|
}); |
|
|
|
this.updateAttrTelemetry(updateResource, null); |
|
|
|
} |
|
|
|
|
|
|
|
//TODO: review and optimize the logic to minimize number of the requests to device.
|
|
|
|
private void onDeviceProfileUpdate(List<LwM2mClient> clients, Lwm2mDeviceProfileTransportConfiguration oldProfile, DeviceProfile deviceProfile) { |
|
|
|
private void onDeviceProfileUpdate(List<LwM2mClient> clients, Lwm2mDeviceProfileTransportConfiguration oldProfileTransportConfiguration, DeviceProfile deviceProfile) { |
|
|
|
if (clientContext.profileUpdate(deviceProfile) != null) { |
|
|
|
TelemetryMappingConfiguration oldTelemetryParams = oldProfile.getObserveAttr(); |
|
|
|
Set<String> attributeSetOld = oldTelemetryParams.getAttribute(); |
|
|
|
Set<String> telemetrySetOld = oldTelemetryParams.getTelemetry(); |
|
|
|
Set<String> observeOld = oldTelemetryParams.getObserve(); |
|
|
|
Map<String, String> keyNameOld = oldTelemetryParams.getKeyName(); |
|
|
|
Map<String, ObjectAttributes> attributeLwm2mOld = oldTelemetryParams.getAttributeLwm2m(); |
|
|
|
|
|
|
|
var newProfile = clientContext.getProfile(deviceProfile.getUuidId()); |
|
|
|
TelemetryMappingConfiguration newTelemetryParams = newProfile.getObserveAttr(); |
|
|
|
Set<String> attributeSetNew = newTelemetryParams.getAttribute(); |
|
|
|
Set<String> telemetrySetNew = newTelemetryParams.getTelemetry(); |
|
|
|
Set<String> observeNew = newTelemetryParams.getObserve(); |
|
|
|
Map<String, String> keyNameNew = newTelemetryParams.getKeyName(); |
|
|
|
Map<String, ObjectAttributes> attributeLwm2mNew = newTelemetryParams.getAttributeLwm2m(); |
|
|
|
|
|
|
|
Set<String> observeToAdd = diffSets(observeOld, observeNew); |
|
|
|
Set<String> observeToRemove = diffSets(observeNew, observeOld); |
|
|
|
|
|
|
|
Set<String> newObjectsToRead = new HashSet<>(); |
|
|
|
Set<String> newObjectsToCancelRead = new HashSet<>(); |
|
|
|
var newProfileTransportConfiguration = clientContext.getProfile(clients.get(0).getRegistration()); |
|
|
|
ParametersUpdateAnalyzeResult parametersUpdate = getParametersUpdate(oldProfileTransportConfiguration, newProfileTransportConfiguration); |
|
|
|
ParametersObserveAnalyzeResult parametersObserve = getParametersObserve(oldProfileTransportConfiguration.getObserveAttr(), newProfileTransportConfiguration.getObserveAttr(), deviceProfile.getId().getId()); |
|
|
|
compareAndSetWriteAttributesObservations(clients, parametersUpdate, parametersObserve); |
|
|
|
updateValueOta(clients, newProfileTransportConfiguration, oldProfileTransportConfiguration); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!attributeSetOld.equals(attributeSetNew)) { |
|
|
|
newObjectsToRead.addAll(diffSets(attributeSetOld, attributeSetNew)); |
|
|
|
newObjectsToCancelRead.addAll(diffSets(attributeSetNew, attributeSetOld)); |
|
|
|
private ParametersUpdateAnalyzeResult getParametersUpdate(Lwm2mDeviceProfileTransportConfiguration oldProfile, Lwm2mDeviceProfileTransportConfiguration newProfile){ |
|
|
|
TelemetryMappingConfiguration newTelemetryParams = newProfile.getObserveAttr(); |
|
|
|
Map<String, String> keyNameNew = newTelemetryParams.getKeyName(); |
|
|
|
Map<String, ObjectAttributes> attributeLwm2mNew = newTelemetryParams.getAttributeLwm2m(); |
|
|
|
Set<String> attributeSetNew = newTelemetryParams.getAttribute(); |
|
|
|
Set<String> telemetrySetNew = newTelemetryParams.getTelemetry(); |
|
|
|
|
|
|
|
} |
|
|
|
if (!telemetrySetOld.equals(telemetrySetNew)) { |
|
|
|
newObjectsToRead.addAll(diffSets(telemetrySetOld, telemetrySetNew)); |
|
|
|
newObjectsToCancelRead.addAll(diffSets(telemetrySetNew, telemetrySetOld)); |
|
|
|
} |
|
|
|
if (!keyNameOld.equals(keyNameNew)) { |
|
|
|
ParametersAnalyzeResult keyNameChange = this.getAnalyzerKeyName(keyNameOld, keyNameNew); |
|
|
|
newObjectsToRead.addAll(keyNameChange.getPathPostParametersAdd()); |
|
|
|
} |
|
|
|
TelemetryMappingConfiguration oldTelemetryParams = oldProfile.getObserveAttr(); |
|
|
|
Map<String, String> keyNameOld = oldTelemetryParams.getKeyName(); |
|
|
|
Map<String, ObjectAttributes> attributeLwm2mOld = oldTelemetryParams.getAttributeLwm2m(); |
|
|
|
ParametersAnalyzeResult analyzerParameters = getAttributesAnalyzer(attributeLwm2mOld, attributeLwm2mNew); |
|
|
|
|
|
|
|
ParametersAnalyzeResult analyzerParameters = getAttributesAnalyzer(attributeLwm2mOld, attributeLwm2mNew); |
|
|
|
// analyze Read
|
|
|
|
Set<String> newObjectsToRead = new HashSet<>(); |
|
|
|
Set<String> newObjectsToCancelRead = new HashSet<>(); |
|
|
|
|
|
|
|
clients.forEach(client -> { |
|
|
|
LwM2MModelConfig modelConfig = new LwM2MModelConfig(client.getEndpoint()); |
|
|
|
modelConfig.getToRead().addAll(diffSets(observeToAdd, newObjectsToRead)); |
|
|
|
modelConfig.getToCancelRead().addAll(newObjectsToCancelRead); |
|
|
|
modelConfig.getToCancelObserve().addAll(observeToRemove); |
|
|
|
modelConfig.getToObserve().addAll(observeToAdd); |
|
|
|
|
|
|
|
Set<String> clientObjects = clientContext.getSupportedIdVerInClient(client); |
|
|
|
Set<String> pathToAdd = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
|
|
|
.collect(Collectors.toUnmodifiableSet()); |
|
|
|
modelConfig.getAttributesToAdd().putAll(pathToAdd.stream().collect(Collectors.toMap(t -> t, attributeLwm2mNew::get))); |
|
|
|
|
|
|
|
Set<String> pathToRemove = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
|
|
|
.collect(Collectors.toUnmodifiableSet()); |
|
|
|
modelConfig.getAttributesToRemove().addAll(pathToRemove); |
|
|
|
|
|
|
|
modelConfigService.sendUpdates(client, modelConfig); |
|
|
|
}); |
|
|
|
Set<String> attributeSetOld = oldTelemetryParams.getAttribute(); |
|
|
|
Set<String> telemetrySetOld = oldTelemetryParams.getTelemetry(); |
|
|
|
|
|
|
|
// update value in fwInfo
|
|
|
|
OtherConfiguration newLwM2mSettings = newProfile.getClientLwM2mSettings(); |
|
|
|
OtherConfiguration oldLwM2mSettings = oldProfile.getClientLwM2mSettings(); |
|
|
|
if (!newLwM2mSettings.getFwUpdateStrategy().equals(oldLwM2mSettings.getFwUpdateStrategy()) |
|
|
|
|| (StringUtils.isNotEmpty(newLwM2mSettings.getFwUpdateResource()) && |
|
|
|
!newLwM2mSettings.getFwUpdateResource().equals(oldLwM2mSettings.getFwUpdateResource()))) { |
|
|
|
clients.forEach(lwM2MClient -> otaService.onFirmwareStrategyUpdate(lwM2MClient, newLwM2mSettings)); |
|
|
|
} |
|
|
|
if (!attributeSetOld.equals(attributeSetNew)) { |
|
|
|
newObjectsToRead.addAll(diffSets(attributeSetOld, attributeSetNew)); |
|
|
|
newObjectsToCancelRead.addAll(diffSets(attributeSetNew, attributeSetOld)); |
|
|
|
|
|
|
|
if (!newLwM2mSettings.getSwUpdateStrategy().equals(oldLwM2mSettings.getSwUpdateStrategy()) |
|
|
|
|| (StringUtils.isNotEmpty(newLwM2mSettings.getSwUpdateResource()) && |
|
|
|
!newLwM2mSettings.getSwUpdateResource().equals(oldLwM2mSettings.getSwUpdateResource()))) { |
|
|
|
clients.forEach(lwM2MClient -> otaService.onCurrentSoftwareStrategyUpdate(lwM2MClient, newLwM2mSettings)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!telemetrySetOld.equals(telemetrySetNew)) { |
|
|
|
newObjectsToRead.addAll(diffSets(telemetrySetOld, telemetrySetNew)); |
|
|
|
newObjectsToCancelRead.addAll(diffSets(telemetrySetNew, telemetrySetOld)); |
|
|
|
} |
|
|
|
if (!keyNameOld.equals(keyNameNew)) { |
|
|
|
ParametersAnalyzeResult keyNameChange = this.getAnalyzerKeyName(keyNameOld, keyNameNew); |
|
|
|
newObjectsToRead.addAll(keyNameChange.getPathPostParametersAdd()); |
|
|
|
} |
|
|
|
return new ParametersUpdateAnalyzeResult(analyzerParameters, newObjectsToRead, newObjectsToCancelRead, attributeLwm2mNew); |
|
|
|
} |
|
|
|
|
|
|
|
private ParametersAnalyzeResult getAnalyzerKeyName(Map<String, String> keyNameOld, Map<String, String> keyNameNew) { |
|
|
|
@ -893,6 +932,55 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
return analyzerParameters; |
|
|
|
} |
|
|
|
|
|
|
|
private ParametersObserveAnalyzeResult getParametersObserve(TelemetryMappingConfiguration oldTelemetryParams, TelemetryMappingConfiguration newTelemetryParams, UUID profileId){ |
|
|
|
try { |
|
|
|
TelemetryObserveStrategy observeStrategyOld = oldTelemetryParams.getObserveStrategy(); |
|
|
|
TelemetryObserveStrategy observeStrategyNew = newTelemetryParams.getObserveStrategy(); |
|
|
|
Set<String> observeOld = oldTelemetryParams.getObserve(); |
|
|
|
Set<String> observeNew = newTelemetryParams.getObserve(); |
|
|
|
Set<String> observeSingleToNew = diffSets(observeOld, observeNew); |
|
|
|
Set<String> observeSingleToCancel = diffSets(observeNew, observeOld); |
|
|
|
if (!observeSingleToNew.isEmpty() || !observeSingleToCancel.isEmpty()) { |
|
|
|
ParametersObserveAnalyzeResult observeAnalyzeResult = new ParametersObserveAnalyzeResult(observeSingleToCancel, |
|
|
|
observeSingleToNew, observeStrategyOld, observeStrategyNew); |
|
|
|
if (SINGLE.equals(observeStrategyOld) && SINGLE.equals(observeStrategyNew)) { |
|
|
|
return observeAnalyzeResult; |
|
|
|
} else if (COMPOSITE_BY_OBJECT.equals(observeStrategyOld) && COMPOSITE_BY_OBJECT.equals(observeStrategyNew)) { |
|
|
|
Map<Integer, String[]> observeByObjectToCancel = new ConcurrentHashMap<>(); |
|
|
|
Map<Integer, String[]> observeByObjectToNew = new ConcurrentHashMap<>(); |
|
|
|
Map<Integer, String[]> observeByObjectOld = groupByObjectIdVersionedIds(observeOld); |
|
|
|
Map<Integer, String[]> observeByObjectNew = groupByObjectIdVersionedIds(observeNew); |
|
|
|
for (Map.Entry<Integer, String[]> entry : observeByObjectNew.entrySet()) { |
|
|
|
Integer key = entry.getKey(); |
|
|
|
String[] newValue = entry.getValue(); |
|
|
|
if (observeByObjectOld.containsKey(key)) { |
|
|
|
String[] oldValue = observeByObjectOld.get(key); |
|
|
|
if (!areArraysStringEqual(oldValue, newValue)) { |
|
|
|
observeByObjectToCancel.put(key, oldValue); |
|
|
|
observeByObjectToNew.put(key, newValue); |
|
|
|
} |
|
|
|
} else { |
|
|
|
observeByObjectToNew.put(key, newValue); |
|
|
|
} |
|
|
|
} |
|
|
|
observeAnalyzeResult.setObserveByObjectToCancel(observeByObjectToCancel); |
|
|
|
observeAnalyzeResult.setObserveByObjectToNew(observeByObjectToNew); |
|
|
|
return observeAnalyzeResult; |
|
|
|
} else { |
|
|
|
// Observe Cancel All
|
|
|
|
observeAnalyzeResult.setObserveSingleToCancel(observeOld); |
|
|
|
// Observe All new
|
|
|
|
observeAnalyzeResult.setObserveSingleToNew(observeNew); |
|
|
|
return observeAnalyzeResult; |
|
|
|
} |
|
|
|
} |
|
|
|
return new ParametersObserveAnalyzeResult(); |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
log.error("Error lwm2m on Profile Update id: [{}]. Failed observe Strategy: [{}]", profileId, e.getMessage()); |
|
|
|
return new ParametersObserveAnalyzeResult(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private ParametersAnalyzeResult getAttributesAnalyzer(Map<String, ObjectAttributes> attributeLwm2mOld, Map<String, ObjectAttributes> attributeLwm2mNew) { |
|
|
|
ParametersAnalyzeResult analyzerParameters = new ParametersAnalyzeResult(); |
|
|
|
Set<String> pathOld = attributeLwm2mOld.keySet(); |
|
|
|
@ -909,8 +997,37 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
return analyzerParameters; |
|
|
|
} |
|
|
|
|
|
|
|
private void compareAndSetWriteAttributes(LwM2mClient client, ParametersAnalyzeResult analyzerParameters, Map<String, ObjectAttributes> lwm2mAttributesNew, LwM2MModelConfig modelConfig) { |
|
|
|
private void compareAndSetWriteAttributesObservations(List<LwM2mClient> clients, ParametersUpdateAnalyzeResult parametersUpdate, ParametersObserveAnalyzeResult parametersObserve) { |
|
|
|
clients.forEach(client -> { |
|
|
|
Set<String> clientObjects = clientContext.getSupportedIdVerInClient(client); |
|
|
|
Set<String> pathToAdd = parametersUpdate.getAnalyzerParameters().getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
|
|
|
.collect(Collectors.toUnmodifiableSet()); |
|
|
|
Map<String, ObjectAttributes> attributesToAdd = pathToAdd.stream().collect(Collectors.toMap(t -> t, parametersUpdate.getAttributeLwm2mNew()::get)); |
|
|
|
Set<String> attributesToRemove = parametersUpdate.getAnalyzerParameters().getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
|
|
|
.collect(Collectors.toUnmodifiableSet()); |
|
|
|
Set<String> toRead = diffSets(parametersObserve.getObserveSingleToNew(), parametersUpdate.getNewObjectsToRead()); |
|
|
|
LwM2MModelConfig modelConfig = new LwM2MModelConfig(client.getEndpoint(), attributesToAdd, attributesToRemove, parametersObserve.getObserveSingleToNew(), |
|
|
|
parametersObserve.getObserveSingleToCancel(), parametersObserve.getObserveByObjectToNew(), parametersObserve.getObserveByObjectToCancel(), |
|
|
|
toRead, parametersObserve.getObserveStrategyOld(), parametersObserve.getObserveStrategyNew()); |
|
|
|
modelConfig.getToCancelRead().addAll(parametersUpdate.getNewObjectsToCancelRead()); |
|
|
|
modelConfigService.sendUpdates(client, modelConfig); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateValueOta(List<LwM2mClient> clients, Lwm2mDeviceProfileTransportConfiguration oldProfile, Lwm2mDeviceProfileTransportConfiguration newProfile) { |
|
|
|
OtherConfiguration newLwM2mSettings = newProfile.getClientLwM2mSettings(); |
|
|
|
OtherConfiguration oldLwM2mSettings = oldProfile.getClientLwM2mSettings(); |
|
|
|
if (!newLwM2mSettings.getFwUpdateStrategy().equals(oldLwM2mSettings.getFwUpdateStrategy()) |
|
|
|
|| (StringUtils.isNotEmpty(newLwM2mSettings.getFwUpdateResource()) && |
|
|
|
!newLwM2mSettings.getFwUpdateResource().equals(oldLwM2mSettings.getFwUpdateResource()))) { |
|
|
|
clients.forEach(lwM2MClient -> otaService.onFirmwareStrategyUpdate(lwM2MClient, newLwM2mSettings)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!newLwM2mSettings.getSwUpdateStrategy().equals(oldLwM2mSettings.getSwUpdateStrategy()) |
|
|
|
|| (StringUtils.isNotEmpty(newLwM2mSettings.getSwUpdateResource()) && |
|
|
|
!newLwM2mSettings.getSwUpdateResource().equals(oldLwM2mSettings.getSwUpdateResource()))) { |
|
|
|
clients.forEach(lwM2MClient -> otaService.onCurrentSoftwareStrategyUpdate(lwM2MClient, newLwM2mSettings)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -987,7 +1104,7 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
} |
|
|
|
|
|
|
|
private Map<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { |
|
|
|
Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); |
|
|
|
Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getRegistration()); |
|
|
|
return profile.getObserveAttr().getKeyName(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -1023,5 +1140,4 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl |
|
|
|
clientContext.update(lwM2MClient); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|