added power mode to lwm2m-device-profile-transport-configuration

This commit is contained in:
YevhenBondarenko 2021-06-24 10:53:35 +03:00
parent ba507e9910
commit a665b2cbe6
25 changed files with 186 additions and 186 deletions

View File

@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.PowerMode;
import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
@ -459,6 +461,13 @@ public class DefaultTransportApiService implements TransportApiService {
} }
private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException {
PowerMode powerMode = null;
switch (device.getDeviceData().getTransportConfiguration().getType()) {
case LWM2M:
powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode();
break;
}
return DeviceInfoProto.newBuilder() return DeviceInfoProto.newBuilder()
.setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits()) .setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits())
.setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits()) .setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits())
@ -471,6 +480,7 @@ public class DefaultTransportApiService implements TransportApiService {
.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits())
.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits())
.setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())) .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo()))
.setPowerMode(powerMode != null ? powerMode.name() : null)
.build(); .build();
} }

View File

@ -20,9 +20,6 @@ import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration;
import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration;
import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -30,6 +27,8 @@ import java.util.Map;
@Data @Data
public class Lwm2mDeviceTransportConfiguration implements DeviceTransportConfiguration { public class Lwm2mDeviceTransportConfiguration implements DeviceTransportConfiguration {
private PowerMode powerMode;
@JsonIgnore @JsonIgnore
private Map<String, Object> properties = new HashMap<>(); private Map<String, Object> properties = new HashMap<>();

View File

@ -115,6 +115,7 @@ message DeviceInfoProto {
int64 deviceProfileIdLSB = 9; int64 deviceProfileIdLSB = 9;
int64 customerIdMSB = 10; int64 customerIdMSB = 10;
int64 customerIdLSB = 11; int64 customerIdLSB = 11;
string powerMode = 12;
} }
/** /**

View File

@ -44,7 +44,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC
import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.data.security.DeviceTokenCredentials; import org.thingsboard.server.common.data.security.DeviceTokenCredentials;
import org.thingsboard.server.common.msg.session.FeatureType; import org.thingsboard.server.common.msg.session.FeatureType;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
@ -515,23 +514,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
successful = false; successful = false;
} }
if (msg.getPersisted()) { coapTransportResource.transportService.process(sessionInfo, msg, !successful, TransportServiceCallback.EMPTY);
RpcStatus status;
if (!successful) {
status = RpcStatus.FAILED;
} else if (msg.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(msg.getRequestId())
.setRequestIdLSB(msg.getRequestIdLSB())
.setRequestIdMSB(msg.getRequestIdMSB())
.setStatus(status.name())
.build();
coapTransportResource.transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY);
}
} }
@Override @Override

View File

@ -406,21 +406,7 @@ public class DeviceApiController implements TbTransportService {
@Override @Override
public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg msg) { public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg msg) {
responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg, true).toString(), HttpStatus.OK)); responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg, true).toString(), HttpStatus.OK));
if (msg.getPersisted()) { transportService.process(sessionInfo, msg, false, TransportServiceCallback.EMPTY);
RpcStatus status;
if (msg.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(msg.getRequestId())
.setRequestIdLSB(msg.getRequestIdLSB())
.setRequestIdMSB(msg.getRequestIdMSB())
.setStatus(status.name())
.build();
transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY);
}
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException;
import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer;
import java.io.IOException; import java.io.IOException;
@ -84,7 +85,14 @@ public class LwM2mCredentialsSecurityInfoValidator {
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.error("Failed to await credentials!", e); log.error("Failed to await credentials!", e);
} }
return resultSecurityStore[0];
TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0];
if (securityInfo.getSecurityMode() == null) {
throw new LwM2MAuthException();
}
return securityInfo;
} }
/** /**

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.transport.lwm2m.secure; package org.thingsboard.server.transport.lwm2m.secure;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.core.request.UplinkRequest; import org.eclipse.leshan.core.request.UplinkRequest;
import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.registration.Registration;
@ -24,14 +25,15 @@ import org.eclipse.leshan.server.security.SecurityChecker;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@TbLwM2mTransportComponent @TbLwM2mTransportComponent
@Slf4j
public class TbLwM2MAuthorizer implements Authorizer { public class TbLwM2MAuthorizer implements Authorizer {
private final TbLwM2MDtlsSessionStore sessionStorage; private final TbLwM2MDtlsSessionStore sessionStorage;
@ -57,7 +59,12 @@ public class TbLwM2MAuthorizer implements Authorizer {
} }
SecurityInfo expectedSecurityInfo = null; SecurityInfo expectedSecurityInfo = null;
if (securityStore != null) { if (securityStore != null) {
try {
expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint());
} catch (LwM2MAuthException e) {
log.warn("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint());
return null;
}
} }
if (securityChecker.checkSecurityInfo(registration.getEndpoint(), senderIdentity, expectedSecurityInfo)) { if (securityChecker.checkSecurityInfo(registration.getEndpoint(), senderIdentity, expectedSecurityInfo)) {
return registration; return registration;

View File

@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.SessionMsgListener;
import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportServiceCallback;
@ -83,21 +82,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s
@Override @Override
public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) {
this.rpcHandler.onToDeviceRpcRequest(toDeviceRequest, this.sessionInfo); this.rpcHandler.onToDeviceRpcRequest(toDeviceRequest, this.sessionInfo);
if (toDeviceRequest.getPersisted()) { transportService.process(sessionInfo, toDeviceRequest, false, TransportServiceCallback.EMPTY);
RpcStatus status;
if (toDeviceRequest.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(toDeviceRequest.getRequestId())
.setRequestIdLSB(toDeviceRequest.getRequestIdLSB())
.setRequestIdMSB(toDeviceRequest.getRequestIdMSB())
.setStatus(status.name())
.build();
transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY);
}
} }
@Override @Override

View File

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2021 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.client;
public class LwM2MAuthException extends RuntimeException {
private static final long serialVersionUID = 4202690897971364044L;
}

View File

@ -32,6 +32,8 @@ import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.PowerMode;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
@ -79,6 +81,9 @@ public class LwM2mClient implements Cloneable {
@Getter @Getter
private String deviceProfileName; private String deviceProfileName;
@Getter
private PowerMode powerMode;
@Getter @Getter
private String identity; private String identity;
@Getter @Getter
@ -121,6 +126,7 @@ public class LwM2mClient implements Cloneable {
this.profileId = new UUID(session.getDeviceProfileIdMSB(), session.getDeviceProfileIdLSB()); this.profileId = new UUID(session.getDeviceProfileIdMSB(), session.getDeviceProfileIdLSB());
this.deviceName = session.getDeviceName(); this.deviceName = session.getDeviceName();
this.deviceProfileName = session.getDeviceType(); this.deviceProfileName = session.getDeviceType();
this.powerMode = credentials.getDeviceInfo().getPowerMode();
} }
public void lock() { public void lock() {
@ -140,6 +146,7 @@ public class LwM2mClient implements Cloneable {
builder.setDeviceName(deviceName); builder.setDeviceName(deviceName);
deviceProfileOpt.ifPresent(deviceProfile -> updateSession(deviceProfile, builder)); deviceProfileOpt.ifPresent(deviceProfile -> updateSession(deviceProfile, builder));
this.session = builder.build(); this.session = builder.build();
this.powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode();
} }
public void onDeviceProfileUpdate(DeviceProfile deviceProfile) { public void onDeviceProfileUpdate(DeviceProfile deviceProfile) {

View File

@ -37,10 +37,10 @@ import org.eclipse.leshan.server.registration.Registration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.common.util.DonAsynchron;
import org.thingsboard.server.cache.ota.OtaPackageDataCache;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.data.PowerMode;
import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes;
import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration;
import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration;
@ -83,8 +83,6 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttrib
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest;
import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService; import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService;
import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy;
import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy;
import org.thingsboard.server.transport.lwm2m.server.rpc.LwM2MRpcRequestHandler; import org.thingsboard.server.transport.lwm2m.server.rpc.LwM2MRpcRequestHandler;
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
@ -203,8 +201,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
executor.submit(() -> { executor.submit(() -> {
LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint());
try { try {
log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); log.debug("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
if (lwM2MClient != null) {
Optional<SessionInfoProto> oldSessionInfo = this.clientContext.register(lwM2MClient, registration); Optional<SessionInfoProto> oldSessionInfo = this.clientContext.register(lwM2MClient, registration);
if (oldSessionInfo.isPresent()) { if (oldSessionInfo.isPresent()) {
log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB())); log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB()));
@ -213,7 +210,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId()); logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId());
SessionInfoProto sessionInfo = lwM2MClient.getSession(); SessionInfoProto sessionInfo = lwM2MClient.getSession();
transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService)); transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService));
log.warn("40) sessionId [{}] Registering rpc subscription after Registration client", new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder()
.setSessionInfo(sessionInfo) .setSessionInfo(sessionInfo)
.setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN))
@ -224,9 +220,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
this.initClientTelemetry(lwM2MClient); this.initClientTelemetry(lwM2MClient);
this.initAttributes(lwM2MClient); this.initAttributes(lwM2MClient);
otaService.init(lwM2MClient); otaService.init(lwM2MClient);
} else {
log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), null);
}
} catch (LwM2MClientStateException stateException) { } catch (LwM2MClientStateException stateException) {
if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) { if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) {
log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState()); log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState());
@ -410,6 +403,27 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint());
logService.log(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LWM2M_INFO + ": Client is awake!"); logService.log(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LWM2M_INFO + ": Client is awake!");
//TODO: associate endpointId with device information. //TODO: associate endpointId with device information.
LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint());
if (LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) {
Lwm2mDeviceProfileTransportConfiguration deviceProfile = clientContext.getProfile(lwM2MClient.getProfileId());
PowerMode powerMode = lwM2MClient.getPowerMode();
if (powerMode == null) {
powerMode = deviceProfile.getClientLwM2mSettings().getPowerMode();
}
if (powerMode.equals(PowerMode.PSM) || powerMode.equals(PowerMode.E_DRX)) {
initAttributes(lwM2MClient);
TransportProtos.TransportToDeviceActorMsg toDeviceActorMsg = TransportProtos.TransportToDeviceActorMsg
.newBuilder()
.setSessionInfo(lwM2MClient.getSession())
.setSendPendingRPC(TransportProtos.SendPendingRPCMsg.newBuilder().build())
.build();
transportService.process(toDeviceActorMsg, TransportServiceCallback.EMPTY);
}
}
} }
/** /**
@ -709,7 +723,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
this.updateResourcesValue(client, resource, path + "/" + resId); this.updateResourcesValue(client, resource, path + "/" + resId);
}); });
} }
} }
//TODO: review and optimize the logic to minimize number of the requests to device. //TODO: review and optimize the logic to minimize number of the requests to device.
@ -920,16 +933,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
} }
} }
private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) {
return TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setType(nameFwSW)
.build();
}
private Map<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { private Map<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) {
Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId());
return profile.getObserveAttr().getKeyName(); return profile.getObserveAttr().getKeyName();

View File

@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.device.profile.MqttTopics;
import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.msg.EncryptionUtil;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.SessionMsgListener;
@ -819,25 +818,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
.ifPresent(payload -> { .ifPresent(payload -> {
ChannelFuture channelFuture = deviceSessionCtx.getChannel().writeAndFlush(payload); ChannelFuture channelFuture = deviceSessionCtx.getChannel().writeAndFlush(payload);
if (rpcRequest.getPersisted()) { if (rpcRequest.getPersisted()) {
channelFuture.addListener(future -> { channelFuture.addListener(future ->
RpcStatus status; transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest,
Throwable t = future.cause(); future.cause() != null, TransportServiceCallback.EMPTY)
if (t != null) { );
log.error("Failed delivering RPC command to device!", t);
status = RpcStatus.FAILED;
} else if (rpcRequest.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(rpcRequest.getRequestId())
.setRequestIdLSB(rpcRequest.getRequestIdLSB())
.setRequestIdMSB(rpcRequest.getRequestIdMSB())
.setStatus(status.name())
.build();
transportService.process(deviceSessionCtx.getSessionInfo(), msg, TransportServiceCallback.EMPTY);
});
} }
}); });
} catch (Exception e) { } catch (Exception e) {

View File

@ -18,7 +18,6 @@ package org.thingsboard.server.transport.mqtt.session;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.SessionMsgListener;
import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportServiceCallback;
@ -100,25 +99,9 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple
payload -> { payload -> {
ChannelFuture channelFuture = parent.writeAndFlush(payload); ChannelFuture channelFuture = parent.writeAndFlush(payload);
if (request.getPersisted()) { if (request.getPersisted()) {
channelFuture.addListener(future -> { channelFuture.addListener(future ->
RpcStatus status; transportService.process(getSessionInfo(), request, future.cause() != null, TransportServiceCallback.EMPTY)
Throwable t = future.cause(); );
if (t != null) {
log.error("Failed delivering RPC command to device!", t);
status = RpcStatus.FAILED;
} else if (request.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(request.getRequestId())
.setRequestIdLSB(request.getRequestIdLSB())
.setRequestIdMSB(request.getRequestIdMSB())
.setStatus(status.name())
.build();
transportService.process(getSessionInfo(), msg, TransportServiceCallback.EMPTY);
});
} }
} }
); );

View File

@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.SessionMsgListener;
import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
@ -141,21 +140,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
@Override @Override
public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) {
snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest); snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest);
if (toDeviceRequest.getPersisted()) { snmpTransportContext.getTransportService().process(getSessionInfo(), toDeviceRequest, false, TransportServiceCallback.EMPTY);
RpcStatus status;
if (toDeviceRequest.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(toDeviceRequest.getRequestId())
.setRequestIdLSB(toDeviceRequest.getRequestIdLSB())
.setRequestIdMSB(toDeviceRequest.getRequestIdMSB())
.setStatus(status.name())
.build();
snmpTransportContext.getTransportService().process(getSessionInfo(), responseMsg, TransportServiceCallback.EMPTY);
}
} }
@Override @Override

View File

@ -21,7 +21,6 @@ import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGateway
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.SessionMetaData;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg;
@ -30,9 +29,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg;
@ -50,8 +49,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToRPCMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionInfoProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCredRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCredRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
@ -110,7 +109,7 @@ public interface TransportService {
void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback); void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback);
void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback<Void> callback); void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback<Void> callback);
void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback<Void> callback); void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback<Void> callback);

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.common.transport.auth; package org.thingsboard.server.common.transport.auth;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.device.data.PowerMode;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -30,6 +31,7 @@ public class TransportDeviceInfo {
private DeviceId deviceId; private DeviceId deviceId;
private String deviceName; private String deviceName;
private String deviceType; private String deviceType;
private PowerMode powerMode;
private String additionalInfo; private String additionalInfo;
} }

View File

@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.device.data.PowerMode;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -42,6 +43,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.ServiceQueue; import org.thingsboard.server.common.msg.queue.ServiceQueue;
@ -439,6 +441,9 @@ public class DefaultTransportService implements TransportService {
tdi.setAdditionalInfo(di.getAdditionalInfo()); tdi.setAdditionalInfo(di.getAdditionalInfo());
tdi.setDeviceName(di.getDeviceName()); tdi.setDeviceName(di.getDeviceName());
tdi.setDeviceType(di.getDeviceType()); tdi.setDeviceType(di.getDeviceType());
if (di.getPowerMode() != null) {
tdi.setPowerMode(PowerMode.valueOf(di.getPowerMode()));
}
return tdi; return tdi;
} }
@ -558,11 +563,30 @@ public class DefaultTransportService implements TransportService {
} }
@Override @Override
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback<Void> callback) { public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) { if (msg.getPersisted()) {
RpcStatus status;
if (isFailedRpc) {
status = RpcStatus.FAILED;
} else if (msg.getOneway()) {
status = RpcStatus.SUCCESSFUL;
} else {
status = RpcStatus.DELIVERED;
}
TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
.setRequestId(msg.getRequestId())
.setRequestIdLSB(msg.getRequestIdLSB())
.setRequestIdMSB(msg.getRequestIdMSB())
.setStatus(status.name())
.build();
if (checkLimits(sessionInfo, responseMsg, callback)) {
reportActivityInternal(sessionInfo); reportActivityInternal(sessionInfo);
sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(msg).build(), sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(responseMsg).build(),
new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, TransportServiceCallback.EMPTY));
}
} }
} }

View File

@ -151,13 +151,12 @@
</mat-form-field> </mat-form-field>
</fieldset> </fieldset>
<fieldset class="fields-group"> <fieldset class="fields-group">
<legend class="group-title" translate>device-profile.lwm2m.power-mode</legend> <legend class="group-title" translate>device-profile.power-saving-mode</legend>
<mat-form-field class="mat-block" fxFlex> <mat-form-field class="mat-block" fxFlex>
<mat-label> </mat-label> <mat-label> </mat-label>
<mat-select formControlName="powerMode"> <mat-select formControlName="powerMode">
<mat-option *ngFor="let powerMode of powerModeLwM2MTypes" <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod">
[value]="powerMode"> {{ powerModeTranslationMap.get(powerMod) | translate}}
{{ powerModeLwM2MNamesMap.get(powerModeLwM2MType[powerMode]) }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>

View File

@ -32,7 +32,7 @@ import {
ModelValue, ModelValue,
ObjectLwM2M, ObjectLwM2M,
OBSERVE, OBSERVE,
OBSERVE_ATTR_TELEMETRY, powerMode, powerModeNames, OBSERVE_ATTR_TELEMETRY, PowerMode, PowerModeTranslationMap,
RESOURCES, RESOURCES,
TELEMETRY TELEMETRY
} from './lwm2m-profile-config.models'; } from './lwm2m-profile-config.models';
@ -72,9 +72,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
sortFunction: (key: string, value: object) => object; sortFunction: (key: string, value: object) => object;
isFwUpdateStrategy: boolean; isFwUpdateStrategy: boolean;
isSwUpdateStrategy: boolean; isSwUpdateStrategy: boolean;
powerModeLwM2MType = powerMode; powerMods = Object.values(PowerMode);
powerModeLwM2MTypes = Object.keys(powerMode); powerModeTranslationMap = PowerModeTranslationMap;
powerModeLwM2MNamesMap = powerModeNames;
get required(): boolean { get required(): boolean {
return this.requiredValue; return this.requiredValue;
@ -208,7 +207,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
private updateWriteValue = (value: ModelValue): void => { private updateWriteValue = (value: ModelValue): void => {
const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ?
this.configurationValue.clientLwM2mSettings.fwUpdateResource : ''; this.configurationValue.clientLwM2mSettings.fwUpdateResource : '';
const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.swUpdateResource) ?
this.configurationValue.clientLwM2mSettings.swUpdateResource : ''; this.configurationValue.clientLwM2mSettings.swUpdateResource : '';
this.lwm2mDeviceProfileFormGroup.patchValue({ this.lwm2mDeviceProfileFormGroup.patchValue({
objectIds: value, objectIds: value,

View File

@ -128,17 +128,17 @@ export const securityConfigModeNames = new Map<securityConfigMode, string>(
] ]
); );
export enum powerMode { export enum PowerMode {
PSM = 'PSM', PSM = 'PSM',
DRX = 'DRX', DRX = 'DRX',
E_DRX = 'E_DRX' E_DRX = 'E_DRX'
} }
export const powerModeNames = new Map<powerMode, string>( export const PowerModeTranslationMap = new Map<PowerMode, string>(
[ [
[powerMode.PSM, 'Power Saving Mode (PSM)'], [PowerMode.PSM, 'device-profile.power-saving-mode-type.psm'],
[powerMode.DRX, 'Discontinuous Reception (DRX)'], [PowerMode.DRX, 'device-profile.power-saving-mode-type.drx'],
[powerMode.E_DRX, 'Extended Discontinuous Reception (eDRX)'] [PowerMode.E_DRX, 'device-profile.power-saving-mode-type.edrx']
] ]
); );
@ -187,7 +187,7 @@ export interface ClientLwM2mSettings {
swUpdateStrategy: number; swUpdateStrategy: number;
fwUpdateResource: string; fwUpdateResource: string;
swUpdateResource: string; swUpdateResource: string;
powerMode: powerMode; powerMode: PowerMode;
} }
export interface ObservableAttributes { export interface ObservableAttributes {
@ -260,7 +260,7 @@ function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings {
swUpdateStrategy: 1, swUpdateStrategy: 1,
fwUpdateResource: DEFAULT_FW_UPDATE_RESOURCE, fwUpdateResource: DEFAULT_FW_UPDATE_RESOURCE,
swUpdateResource: DEFAULT_SW_UPDATE_RESOURCE, swUpdateResource: DEFAULT_SW_UPDATE_RESOURCE,
powerMode: powerMode.DRX powerMode: PowerMode.DRX
}; };
} }

View File

@ -29,12 +29,12 @@
formControlName="configuration"> formControlName="configuration">
</tb-mqtt-device-transport-configuration> </tb-mqtt-device-transport-configuration>
</ng-template> </ng-template>
<!--ng-template [ngSwitchCase]="deviceTransportType.LWM2M"> <ng-template [ngSwitchCase]="deviceTransportType.LWM2M">
<tb-lwm2m-device-transport-configuration <tb-lwm2m-device-transport-configuration
[required]="required" [required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-lwm2m-device-transport-configuration> </tb-lwm2m-device-transport-configuration>
</ng-template--> </ng-template>
<ng-template [ngSwitchCase]="deviceTransportType.COAP"> <ng-template [ngSwitchCase]="deviceTransportType.COAP">
<tb-coap-device-transport-configuration <tb-coap-device-transport-configuration
[required]="required" [required]="required"

View File

@ -16,9 +16,13 @@
--> -->
<form [formGroup]="lwm2mDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;"> <form [formGroup]="lwm2mDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;">
<!--tb-json-object-edit <mat-form-field class="mat-block" fxFlex>
[required]="required" <mat-label translate>device-profile.power-saving-mode</mat-label>
label="{{ 'device-profile.transport-type-lwm2m' | translate }}" <mat-select formControlName="powerMode">
formControlName="configuration"> <mat-option [value]="null">{{ "device-profile.power-saving-mode-type.default" | translate }}</mat-option>
</tb-json-object-edit--> <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod">
{{ powerModeTranslationMap.get(powerMod) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</form> </form>

View File

@ -23,6 +23,7 @@ import {
DeviceTransportConfiguration, DeviceTransportConfiguration,
DeviceTransportType, Lwm2mDeviceTransportConfiguration DeviceTransportType, Lwm2mDeviceTransportConfiguration
} from '@shared/models/device.models'; } from '@shared/models/device.models';
import {PowerMode, PowerModeTranslationMap} from "@home/components/profile/device/lwm2m/lwm2m-profile-config.models";
@Component({ @Component({
selector: 'tb-lwm2m-device-transport-configuration', selector: 'tb-lwm2m-device-transport-configuration',
@ -37,6 +38,8 @@ import {
export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit { export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit {
lwm2mDeviceTransportConfigurationFormGroup: FormGroup; lwm2mDeviceTransportConfigurationFormGroup: FormGroup;
powerMods = Object.values(PowerMode);
powerModeTranslationMap = PowerModeTranslationMap;
private requiredValue: boolean; private requiredValue: boolean;
get required(): boolean { get required(): boolean {
@ -65,7 +68,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA
ngOnInit() { ngOnInit() {
this.lwm2mDeviceTransportConfigurationFormGroup = this.fb.group({ this.lwm2mDeviceTransportConfigurationFormGroup = this.fb.group({
configuration: [null, Validators.required] powerMode: [null]
}); });
this.lwm2mDeviceTransportConfigurationFormGroup.valueChanges.subscribe(() => { this.lwm2mDeviceTransportConfigurationFormGroup.valueChanges.subscribe(() => {
this.updateModel(); this.updateModel();
@ -82,13 +85,13 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA
} }
writeValue(value: Lwm2mDeviceTransportConfiguration | null): void { writeValue(value: Lwm2mDeviceTransportConfiguration | null): void {
this.lwm2mDeviceTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); this.lwm2mDeviceTransportConfigurationFormGroup.patchValue(value, {emitEvent: false});
} }
private updateModel() { private updateModel() {
let configuration: DeviceTransportConfiguration = null; let configuration: DeviceTransportConfiguration = null;
if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) {
configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration; configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue();
// configuration.type = DeviceTransportType.LWM2M; // configuration.type = DeviceTransportType.LWM2M;
} }
this.propagateChange(configuration); this.propagateChange(configuration);

View File

@ -200,7 +200,7 @@ export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportTy
DeviceTransportType.LWM2M, DeviceTransportType.LWM2M,
{ {
hasProfileConfiguration: true, hasProfileConfiguration: true,
hasDeviceConfiguration: false, hasDeviceConfiguration: true,
} }
], ],
[ [

View File

@ -1213,6 +1213,13 @@
"export-failed-error": "Unable to export device profile: {{error}}", "export-failed-error": "Unable to export device profile: {{error}}",
"device-profile-file": "Device profile file", "device-profile-file": "Device profile file",
"invalid-device-profile-file-error": "Unable to import device profile: Invalid device profile data structure.", "invalid-device-profile-file-error": "Unable to import device profile: Invalid device profile data structure.",
"power-saving-mode": "Power Saving Mode",
"power-saving-mode-type": {
"default": "Use device profile power saving mode",
"psm": "Power Saving Mode (PSM)",
"drx": "Discontinuous Reception (DRX)",
"edrx": "Extended Discontinuous Reception (eDRX)"
},
"lwm2m": { "lwm2m": {
"object-list": "Object list", "object-list": "Object list",
"object-list-empty": "No objects selected.", "object-list-empty": "No objects selected.",