Commit a665b2cbe631dc87ed128b2182cfbc25ddff03c7
1 parent
ba507e99
added power mode to lwm2m-device-profile-transport-configuration
Showing
25 changed files
with
186 additions
and
186 deletions
... | ... | @@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.TbResource; |
41 | 41 | import org.thingsboard.server.common.data.TenantProfile; |
42 | 42 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; |
43 | 43 | import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; |
44 | +import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; | |
45 | +import org.thingsboard.server.common.data.device.data.PowerMode; | |
44 | 46 | import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; |
45 | 47 | import org.thingsboard.server.common.data.id.CustomerId; |
46 | 48 | import org.thingsboard.server.common.data.id.DeviceId; |
... | ... | @@ -459,6 +461,13 @@ public class DefaultTransportApiService implements TransportApiService { |
459 | 461 | } |
460 | 462 | |
461 | 463 | private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { |
464 | + PowerMode powerMode = null; | |
465 | + switch (device.getDeviceData().getTransportConfiguration().getType()) { | |
466 | + case LWM2M: | |
467 | + powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode(); | |
468 | + break; | |
469 | + } | |
470 | + | |
462 | 471 | return DeviceInfoProto.newBuilder() |
463 | 472 | .setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits()) |
464 | 473 | .setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits()) |
... | ... | @@ -471,6 +480,7 @@ public class DefaultTransportApiService implements TransportApiService { |
471 | 480 | .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) |
472 | 481 | .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) |
473 | 482 | .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())) |
483 | + .setPowerMode(powerMode != null ? powerMode.name() : null) | |
474 | 484 | .build(); |
475 | 485 | } |
476 | 486 | ... | ... |
... | ... | @@ -20,9 +20,6 @@ import com.fasterxml.jackson.annotation.JsonAnySetter; |
20 | 20 | import com.fasterxml.jackson.annotation.JsonIgnore; |
21 | 21 | import lombok.Data; |
22 | 22 | import org.thingsboard.server.common.data.DeviceTransportType; |
23 | -import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration; | |
24 | -import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; | |
25 | -import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; | |
26 | 23 | |
27 | 24 | import java.util.HashMap; |
28 | 25 | import java.util.Map; |
... | ... | @@ -30,6 +27,8 @@ import java.util.Map; |
30 | 27 | @Data |
31 | 28 | public class Lwm2mDeviceTransportConfiguration implements DeviceTransportConfiguration { |
32 | 29 | |
30 | + private PowerMode powerMode; | |
31 | + | |
33 | 32 | @JsonIgnore |
34 | 33 | private Map<String, Object> properties = new HashMap<>(); |
35 | 34 | ... | ... |
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
... | ... | @@ -44,7 +44,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC |
44 | 44 | import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; |
45 | 45 | import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; |
46 | 46 | import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; |
47 | -import org.thingsboard.server.common.data.rpc.RpcStatus; | |
48 | 47 | import org.thingsboard.server.common.data.security.DeviceTokenCredentials; |
49 | 48 | import org.thingsboard.server.common.msg.session.FeatureType; |
50 | 49 | import org.thingsboard.server.common.msg.session.SessionMsgType; |
... | ... | @@ -515,23 +514,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { |
515 | 514 | exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); |
516 | 515 | successful = false; |
517 | 516 | } |
518 | - if (msg.getPersisted()) { | |
519 | - RpcStatus status; | |
520 | - if (!successful) { | |
521 | - status = RpcStatus.FAILED; | |
522 | - } else if (msg.getOneway()) { | |
523 | - status = RpcStatus.SUCCESSFUL; | |
524 | - } else { | |
525 | - status = RpcStatus.DELIVERED; | |
526 | - } | |
527 | - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
528 | - .setRequestId(msg.getRequestId()) | |
529 | - .setRequestIdLSB(msg.getRequestIdLSB()) | |
530 | - .setRequestIdMSB(msg.getRequestIdMSB()) | |
531 | - .setStatus(status.name()) | |
532 | - .build(); | |
533 | - coapTransportResource.transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY); | |
534 | - } | |
517 | + coapTransportResource.transportService.process(sessionInfo, msg, !successful, TransportServiceCallback.EMPTY); | |
535 | 518 | } |
536 | 519 | |
537 | 520 | @Override | ... | ... |
... | ... | @@ -406,21 +406,7 @@ public class DeviceApiController implements TbTransportService { |
406 | 406 | @Override |
407 | 407 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg msg) { |
408 | 408 | responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg, true).toString(), HttpStatus.OK)); |
409 | - if (msg.getPersisted()) { | |
410 | - RpcStatus status; | |
411 | - if (msg.getOneway()) { | |
412 | - status = RpcStatus.SUCCESSFUL; | |
413 | - } else { | |
414 | - status = RpcStatus.DELIVERED; | |
415 | - } | |
416 | - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
417 | - .setRequestId(msg.getRequestId()) | |
418 | - .setRequestIdLSB(msg.getRequestIdLSB()) | |
419 | - .setRequestIdMSB(msg.getRequestIdMSB()) | |
420 | - .setStatus(status.name()) | |
421 | - .build(); | |
422 | - transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY); | |
423 | - } | |
409 | + transportService.process(sessionInfo, msg, false, TransportServiceCallback.EMPTY); | |
424 | 410 | } |
425 | 411 | |
426 | 412 | @Override | ... | ... |
... | ... | @@ -33,6 +33,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
33 | 33 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
34 | 34 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
35 | 35 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; |
36 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; | |
36 | 37 | import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer; |
37 | 38 | |
38 | 39 | import java.io.IOException; |
... | ... | @@ -84,7 +85,14 @@ public class LwM2mCredentialsSecurityInfoValidator { |
84 | 85 | } catch (InterruptedException e) { |
85 | 86 | log.error("Failed to await credentials!", e); |
86 | 87 | } |
87 | - return resultSecurityStore[0]; | |
88 | + | |
89 | + TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0]; | |
90 | + | |
91 | + if (securityInfo.getSecurityMode() == null) { | |
92 | + throw new LwM2MAuthException(); | |
93 | + } | |
94 | + | |
95 | + return securityInfo; | |
88 | 96 | } |
89 | 97 | |
90 | 98 | /** | ... | ... |
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.secure; |
17 | 17 | |
18 | 18 | import lombok.RequiredArgsConstructor; |
19 | +import lombok.extern.slf4j.Slf4j; | |
19 | 20 | import org.eclipse.leshan.core.request.Identity; |
20 | 21 | import org.eclipse.leshan.core.request.UplinkRequest; |
21 | 22 | import org.eclipse.leshan.server.registration.Registration; |
... | ... | @@ -24,14 +25,15 @@ import org.eclipse.leshan.server.security.SecurityChecker; |
24 | 25 | import org.eclipse.leshan.server.security.SecurityInfo; |
25 | 26 | import org.springframework.stereotype.Component; |
26 | 27 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
28 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; | |
27 | 29 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
28 | 30 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
29 | -import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; | |
30 | 31 | import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; |
31 | 32 | |
32 | 33 | @Component |
33 | 34 | @RequiredArgsConstructor |
34 | 35 | @TbLwM2mTransportComponent |
36 | +@Slf4j | |
35 | 37 | public class TbLwM2MAuthorizer implements Authorizer { |
36 | 38 | |
37 | 39 | private final TbLwM2MDtlsSessionStore sessionStorage; |
... | ... | @@ -57,7 +59,12 @@ public class TbLwM2MAuthorizer implements Authorizer { |
57 | 59 | } |
58 | 60 | SecurityInfo expectedSecurityInfo = null; |
59 | 61 | if (securityStore != null) { |
60 | - expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); | |
62 | + try { | |
63 | + expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); | |
64 | + } catch (LwM2MAuthException e) { | |
65 | + log.warn("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint()); | |
66 | + return null; | |
67 | + } | |
61 | 68 | } |
62 | 69 | if (securityChecker.checkSecurityInfo(registration.getEndpoint(), senderIdentity, expectedSecurityInfo)) { |
63 | 70 | return registration; | ... | ... |
... | ... | @@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull; |
23 | 23 | import org.thingsboard.server.common.data.Device; |
24 | 24 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | 25 | import org.thingsboard.server.common.data.ResourceType; |
26 | -import org.thingsboard.server.common.data.rpc.RpcStatus; | |
27 | 26 | import org.thingsboard.server.common.transport.SessionMsgListener; |
28 | 27 | import org.thingsboard.server.common.transport.TransportService; |
29 | 28 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
... | ... | @@ -58,7 +57,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s |
58 | 57 | @Override |
59 | 58 | public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) { |
60 | 59 | this.attributesService.onAttributesUpdate(attributeUpdateNotification, this.sessionInfo); |
61 | - } | |
60 | + } | |
62 | 61 | |
63 | 62 | @Override |
64 | 63 | public void onRemoteSessionCloseCommand(UUID sessionId, SessionCloseNotificationProto sessionCloseNotification) { |
... | ... | @@ -83,21 +82,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s |
83 | 82 | @Override |
84 | 83 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
85 | 84 | this.rpcHandler.onToDeviceRpcRequest(toDeviceRequest, this.sessionInfo); |
86 | - if (toDeviceRequest.getPersisted()) { | |
87 | - RpcStatus status; | |
88 | - if (toDeviceRequest.getOneway()) { | |
89 | - status = RpcStatus.SUCCESSFUL; | |
90 | - } else { | |
91 | - status = RpcStatus.DELIVERED; | |
92 | - } | |
93 | - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
94 | - .setRequestId(toDeviceRequest.getRequestId()) | |
95 | - .setRequestIdLSB(toDeviceRequest.getRequestIdLSB()) | |
96 | - .setRequestIdMSB(toDeviceRequest.getRequestIdMSB()) | |
97 | - .setStatus(status.name()) | |
98 | - .build(); | |
99 | - transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY); | |
100 | - } | |
85 | + transportService.process(sessionInfo, toDeviceRequest, false, TransportServiceCallback.EMPTY); | |
101 | 86 | } |
102 | 87 | |
103 | 88 | @Override | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2021 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.transport.lwm2m.server.client; | |
17 | + | |
18 | +public class LwM2MAuthException extends RuntimeException { | |
19 | + | |
20 | + private static final long serialVersionUID = 4202690897971364044L; | |
21 | + | |
22 | +} | ... | ... |
... | ... | @@ -32,6 +32,8 @@ import org.eclipse.leshan.server.registration.Registration; |
32 | 32 | import org.eclipse.leshan.server.security.SecurityInfo; |
33 | 33 | import org.thingsboard.server.common.data.Device; |
34 | 34 | import org.thingsboard.server.common.data.DeviceProfile; |
35 | +import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; | |
36 | +import org.thingsboard.server.common.data.device.data.PowerMode; | |
35 | 37 | import org.thingsboard.server.common.data.id.TenantId; |
36 | 38 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
37 | 39 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
... | ... | @@ -80,6 +82,9 @@ public class LwM2mClient implements Cloneable { |
80 | 82 | private String deviceProfileName; |
81 | 83 | |
82 | 84 | @Getter |
85 | + private PowerMode powerMode; | |
86 | + | |
87 | + @Getter | |
83 | 88 | private String identity; |
84 | 89 | @Getter |
85 | 90 | private SecurityInfo securityInfo; |
... | ... | @@ -121,6 +126,7 @@ public class LwM2mClient implements Cloneable { |
121 | 126 | this.profileId = new UUID(session.getDeviceProfileIdMSB(), session.getDeviceProfileIdLSB()); |
122 | 127 | this.deviceName = session.getDeviceName(); |
123 | 128 | this.deviceProfileName = session.getDeviceType(); |
129 | + this.powerMode = credentials.getDeviceInfo().getPowerMode(); | |
124 | 130 | } |
125 | 131 | |
126 | 132 | public void lock() { |
... | ... | @@ -140,6 +146,7 @@ public class LwM2mClient implements Cloneable { |
140 | 146 | builder.setDeviceName(deviceName); |
141 | 147 | deviceProfileOpt.ifPresent(deviceProfile -> updateSession(deviceProfile, builder)); |
142 | 148 | this.session = builder.build(); |
149 | + this.powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode(); | |
143 | 150 | } |
144 | 151 | |
145 | 152 | public void onDeviceProfileUpdate(DeviceProfile deviceProfile) { | ... | ... |
... | ... | @@ -37,10 +37,10 @@ import org.eclipse.leshan.server.registration.Registration; |
37 | 37 | import org.springframework.context.annotation.Lazy; |
38 | 38 | import org.springframework.stereotype.Service; |
39 | 39 | import org.thingsboard.common.util.DonAsynchron; |
40 | -import org.thingsboard.server.cache.ota.OtaPackageDataCache; | |
41 | 40 | import org.thingsboard.server.common.data.Device; |
42 | 41 | import org.thingsboard.server.common.data.DeviceProfile; |
43 | 42 | import org.thingsboard.server.common.data.StringUtils; |
43 | +import org.thingsboard.server.common.data.device.data.PowerMode; | |
44 | 44 | import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; |
45 | 45 | import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; |
46 | 46 | import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; |
... | ... | @@ -83,8 +83,6 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttrib |
83 | 83 | import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; |
84 | 84 | import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService; |
85 | 85 | import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService; |
86 | -import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy; | |
87 | -import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy; | |
88 | 86 | import org.thingsboard.server.transport.lwm2m.server.rpc.LwM2MRpcRequestHandler; |
89 | 87 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
90 | 88 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
... | ... | @@ -203,30 +201,25 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl |
203 | 201 | executor.submit(() -> { |
204 | 202 | LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); |
205 | 203 | try { |
206 | - log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); | |
207 | - if (lwM2MClient != null) { | |
208 | - Optional<SessionInfoProto> oldSessionInfo = this.clientContext.register(lwM2MClient, registration); | |
209 | - if (oldSessionInfo.isPresent()) { | |
210 | - log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB())); | |
211 | - closeSession(oldSessionInfo.get()); | |
212 | - } | |
213 | - logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId()); | |
214 | - SessionInfoProto sessionInfo = lwM2MClient.getSession(); | |
215 | - transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService)); | |
216 | - log.warn("40) sessionId [{}] Registering rpc subscription after Registration client", new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | |
217 | - TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() | |
218 | - .setSessionInfo(sessionInfo) | |
219 | - .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) | |
220 | - .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) | |
221 | - .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) | |
222 | - .build(); | |
223 | - transportService.process(msg, null); | |
224 | - this.initClientTelemetry(lwM2MClient); | |
225 | - this.initAttributes(lwM2MClient); | |
226 | - otaService.init(lwM2MClient); | |
227 | - } else { | |
228 | - log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), null); | |
204 | + log.debug("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); | |
205 | + Optional<SessionInfoProto> oldSessionInfo = this.clientContext.register(lwM2MClient, registration); | |
206 | + if (oldSessionInfo.isPresent()) { | |
207 | + log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB())); | |
208 | + closeSession(oldSessionInfo.get()); | |
229 | 209 | } |
210 | + logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId()); | |
211 | + SessionInfoProto sessionInfo = lwM2MClient.getSession(); | |
212 | + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService)); | |
213 | + TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() | |
214 | + .setSessionInfo(sessionInfo) | |
215 | + .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) | |
216 | + .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) | |
217 | + .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) | |
218 | + .build(); | |
219 | + transportService.process(msg, null); | |
220 | + this.initClientTelemetry(lwM2MClient); | |
221 | + this.initAttributes(lwM2MClient); | |
222 | + otaService.init(lwM2MClient); | |
230 | 223 | } catch (LwM2MClientStateException stateException) { |
231 | 224 | if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) { |
232 | 225 | log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState()); |
... | ... | @@ -410,6 +403,27 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl |
410 | 403 | log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); |
411 | 404 | logService.log(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LWM2M_INFO + ": Client is awake!"); |
412 | 405 | //TODO: associate endpointId with device information. |
406 | + | |
407 | + LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); | |
408 | + | |
409 | + if (LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { | |
410 | + Lwm2mDeviceProfileTransportConfiguration deviceProfile = clientContext.getProfile(lwM2MClient.getProfileId()); | |
411 | + | |
412 | + PowerMode powerMode = lwM2MClient.getPowerMode(); | |
413 | + if (powerMode == null) { | |
414 | + powerMode = deviceProfile.getClientLwM2mSettings().getPowerMode(); | |
415 | + } | |
416 | + | |
417 | + if (powerMode.equals(PowerMode.PSM) || powerMode.equals(PowerMode.E_DRX)) { | |
418 | + initAttributes(lwM2MClient); | |
419 | + TransportProtos.TransportToDeviceActorMsg toDeviceActorMsg = TransportProtos.TransportToDeviceActorMsg | |
420 | + .newBuilder() | |
421 | + .setSessionInfo(lwM2MClient.getSession()) | |
422 | + .setSendPendingRPC(TransportProtos.SendPendingRPCMsg.newBuilder().build()) | |
423 | + .build(); | |
424 | + transportService.process(toDeviceActorMsg, TransportServiceCallback.EMPTY); | |
425 | + } | |
426 | + } | |
413 | 427 | } |
414 | 428 | |
415 | 429 | /** |
... | ... | @@ -709,7 +723,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl |
709 | 723 | this.updateResourcesValue(client, resource, path + "/" + resId); |
710 | 724 | }); |
711 | 725 | } |
712 | - | |
713 | 726 | } |
714 | 727 | |
715 | 728 | //TODO: review and optimize the logic to minimize number of the requests to device. |
... | ... | @@ -920,16 +933,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl |
920 | 933 | } |
921 | 934 | } |
922 | 935 | |
923 | - private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) { | |
924 | - return TransportProtos.GetOtaPackageRequestMsg.newBuilder() | |
925 | - .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | |
926 | - .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) | |
927 | - .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | |
928 | - .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | |
929 | - .setType(nameFwSW) | |
930 | - .build(); | |
931 | - } | |
932 | - | |
933 | 936 | private Map<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { |
934 | 937 | Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); |
935 | 938 | return profile.getObserveAttr().getKeyName(); | ... | ... |
... | ... | @@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.TransportPayloadType; |
50 | 50 | import org.thingsboard.server.common.data.device.profile.MqttTopics; |
51 | 51 | import org.thingsboard.server.common.data.id.OtaPackageId; |
52 | 52 | import org.thingsboard.server.common.data.ota.OtaPackageType; |
53 | -import org.thingsboard.server.common.data.rpc.RpcStatus; | |
54 | 53 | import org.thingsboard.server.common.msg.EncryptionUtil; |
55 | 54 | import org.thingsboard.server.common.msg.tools.TbRateLimitsException; |
56 | 55 | import org.thingsboard.server.common.transport.SessionMsgListener; |
... | ... | @@ -819,25 +818,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement |
819 | 818 | .ifPresent(payload -> { |
820 | 819 | ChannelFuture channelFuture = deviceSessionCtx.getChannel().writeAndFlush(payload); |
821 | 820 | if (rpcRequest.getPersisted()) { |
822 | - channelFuture.addListener(future -> { | |
823 | - RpcStatus status; | |
824 | - Throwable t = future.cause(); | |
825 | - if (t != null) { | |
826 | - log.error("Failed delivering RPC command to device!", t); | |
827 | - status = RpcStatus.FAILED; | |
828 | - } else if (rpcRequest.getOneway()) { | |
829 | - status = RpcStatus.SUCCESSFUL; | |
830 | - } else { | |
831 | - status = RpcStatus.DELIVERED; | |
832 | - } | |
833 | - TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
834 | - .setRequestId(rpcRequest.getRequestId()) | |
835 | - .setRequestIdLSB(rpcRequest.getRequestIdLSB()) | |
836 | - .setRequestIdMSB(rpcRequest.getRequestIdMSB()) | |
837 | - .setStatus(status.name()) | |
838 | - .build(); | |
839 | - transportService.process(deviceSessionCtx.getSessionInfo(), msg, TransportServiceCallback.EMPTY); | |
840 | - }); | |
821 | + channelFuture.addListener(future -> | |
822 | + transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, | |
823 | + future.cause() != null, TransportServiceCallback.EMPTY) | |
824 | + ); | |
841 | 825 | } |
842 | 826 | }); |
843 | 827 | } catch (Exception e) { | ... | ... |
... | ... | @@ -18,7 +18,6 @@ package org.thingsboard.server.transport.mqtt.session; |
18 | 18 | import io.netty.channel.ChannelFuture; |
19 | 19 | import lombok.extern.slf4j.Slf4j; |
20 | 20 | import org.thingsboard.server.common.data.DeviceProfile; |
21 | -import org.thingsboard.server.common.data.rpc.RpcStatus; | |
22 | 21 | import org.thingsboard.server.common.transport.SessionMsgListener; |
23 | 22 | import org.thingsboard.server.common.transport.TransportService; |
24 | 23 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
... | ... | @@ -100,25 +99,9 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple |
100 | 99 | payload -> { |
101 | 100 | ChannelFuture channelFuture = parent.writeAndFlush(payload); |
102 | 101 | if (request.getPersisted()) { |
103 | - channelFuture.addListener(future -> { | |
104 | - RpcStatus status; | |
105 | - Throwable t = future.cause(); | |
106 | - if (t != null) { | |
107 | - log.error("Failed delivering RPC command to device!", t); | |
108 | - status = RpcStatus.FAILED; | |
109 | - } else if (request.getOneway()) { | |
110 | - status = RpcStatus.SUCCESSFUL; | |
111 | - } else { | |
112 | - status = RpcStatus.DELIVERED; | |
113 | - } | |
114 | - TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
115 | - .setRequestId(request.getRequestId()) | |
116 | - .setRequestIdLSB(request.getRequestIdLSB()) | |
117 | - .setRequestIdMSB(request.getRequestIdMSB()) | |
118 | - .setStatus(status.name()) | |
119 | - .build(); | |
120 | - transportService.process(getSessionInfo(), msg, TransportServiceCallback.EMPTY); | |
121 | - }); | |
102 | + channelFuture.addListener(future -> | |
103 | + transportService.process(getSessionInfo(), request, future.cause() != null, TransportServiceCallback.EMPTY) | |
104 | + ); | |
122 | 105 | } |
123 | 106 | } |
124 | 107 | ); | ... | ... |
... | ... | @@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.DeviceProfile; |
26 | 26 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; |
27 | 27 | import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; |
28 | 28 | import org.thingsboard.server.common.data.id.DeviceId; |
29 | -import org.thingsboard.server.common.data.rpc.RpcStatus; | |
30 | 29 | import org.thingsboard.server.common.transport.SessionMsgListener; |
31 | 30 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
32 | 31 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; |
... | ... | @@ -140,22 +139,8 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S |
140 | 139 | |
141 | 140 | @Override |
142 | 141 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
143 | - snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest); | |
144 | - if (toDeviceRequest.getPersisted()) { | |
145 | - RpcStatus status; | |
146 | - if (toDeviceRequest.getOneway()) { | |
147 | - status = RpcStatus.SUCCESSFUL; | |
148 | - } else { | |
149 | - status = RpcStatus.DELIVERED; | |
150 | - } | |
151 | - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
152 | - .setRequestId(toDeviceRequest.getRequestId()) | |
153 | - .setRequestIdLSB(toDeviceRequest.getRequestIdLSB()) | |
154 | - .setRequestIdMSB(toDeviceRequest.getRequestIdMSB()) | |
155 | - .setStatus(status.name()) | |
156 | - .build(); | |
157 | - snmpTransportContext.getTransportService().process(getSessionInfo(), responseMsg, TransportServiceCallback.EMPTY); | |
158 | - } | |
142 | + snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest); | |
143 | + snmpTransportContext.getTransportService().process(getSessionInfo(), toDeviceRequest, false, TransportServiceCallback.EMPTY); | |
159 | 144 | } |
160 | 145 | |
161 | 146 | @Override | ... | ... |
... | ... | @@ -21,7 +21,6 @@ import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGateway |
21 | 21 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
22 | 22 | import org.thingsboard.server.common.transport.service.SessionMetaData; |
23 | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | -import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | |
25 | 24 | import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; |
26 | 25 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; |
27 | 26 | import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg; |
... | ... | @@ -30,9 +29,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg; |
30 | 29 | import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg; |
31 | 30 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; |
32 | 31 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; |
32 | +import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; | |
33 | 33 | import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg; |
34 | 34 | import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg; |
35 | -import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; | |
36 | 35 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg; |
37 | 36 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg; |
38 | 37 | import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg; |
... | ... | @@ -50,8 +49,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToRPCMsg; |
50 | 49 | import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionInfoProto; |
51 | 50 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; |
52 | 51 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg; |
52 | +import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | |
53 | 53 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCredRequestMsg; |
54 | -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; | |
55 | 54 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; |
56 | 55 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; |
57 | 56 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; |
... | ... | @@ -110,7 +109,7 @@ public interface TransportService { |
110 | 109 | |
111 | 110 | void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback); |
112 | 111 | |
113 | - void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback<Void> callback); | |
112 | + void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback<Void> callback); | |
114 | 113 | |
115 | 114 | void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback<Void> callback); |
116 | 115 | ... | ... |
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.common.transport.auth; |
17 | 17 | |
18 | 18 | import lombok.Data; |
19 | +import org.thingsboard.server.common.data.device.data.PowerMode; | |
19 | 20 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | 21 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | 22 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
... | ... | @@ -30,6 +31,7 @@ public class TransportDeviceInfo { |
30 | 31 | private DeviceId deviceId; |
31 | 32 | private String deviceName; |
32 | 33 | private String deviceType; |
34 | + private PowerMode powerMode; | |
33 | 35 | private String additionalInfo; |
34 | 36 | |
35 | 37 | } | ... | ... |
... | ... | @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; |
35 | 35 | import org.thingsboard.server.common.data.EntityType; |
36 | 36 | import org.thingsboard.server.common.data.ResourceType; |
37 | 37 | import org.thingsboard.server.common.data.Tenant; |
38 | +import org.thingsboard.server.common.data.device.data.PowerMode; | |
38 | 39 | import org.thingsboard.server.common.data.id.CustomerId; |
39 | 40 | import org.thingsboard.server.common.data.id.DeviceId; |
40 | 41 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
... | ... | @@ -42,6 +43,7 @@ import org.thingsboard.server.common.data.id.EntityId; |
42 | 43 | import org.thingsboard.server.common.data.id.RuleChainId; |
43 | 44 | import org.thingsboard.server.common.data.id.TenantId; |
44 | 45 | import org.thingsboard.server.common.data.id.TenantProfileId; |
46 | +import org.thingsboard.server.common.data.rpc.RpcStatus; | |
45 | 47 | import org.thingsboard.server.common.msg.TbMsg; |
46 | 48 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
47 | 49 | import org.thingsboard.server.common.msg.queue.ServiceQueue; |
... | ... | @@ -439,6 +441,9 @@ public class DefaultTransportService implements TransportService { |
439 | 441 | tdi.setAdditionalInfo(di.getAdditionalInfo()); |
440 | 442 | tdi.setDeviceName(di.getDeviceName()); |
441 | 443 | tdi.setDeviceType(di.getDeviceType()); |
444 | + if (di.getPowerMode() != null) { | |
445 | + tdi.setPowerMode(PowerMode.valueOf(di.getPowerMode())); | |
446 | + } | |
442 | 447 | return tdi; |
443 | 448 | } |
444 | 449 | |
... | ... | @@ -558,11 +563,30 @@ public class DefaultTransportService implements TransportService { |
558 | 563 | } |
559 | 564 | |
560 | 565 | @Override |
561 | - public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback<Void> callback) { | |
562 | - if (checkLimits(sessionInfo, msg, callback)) { | |
563 | - reportActivityInternal(sessionInfo); | |
564 | - sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(msg).build(), | |
565 | - new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); | |
566 | + public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback<Void> callback) { | |
567 | + if (msg.getPersisted()) { | |
568 | + RpcStatus status; | |
569 | + | |
570 | + if (isFailedRpc) { | |
571 | + status = RpcStatus.FAILED; | |
572 | + } else if (msg.getOneway()) { | |
573 | + status = RpcStatus.SUCCESSFUL; | |
574 | + } else { | |
575 | + status = RpcStatus.DELIVERED; | |
576 | + } | |
577 | + | |
578 | + TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() | |
579 | + .setRequestId(msg.getRequestId()) | |
580 | + .setRequestIdLSB(msg.getRequestIdLSB()) | |
581 | + .setRequestIdMSB(msg.getRequestIdMSB()) | |
582 | + .setStatus(status.name()) | |
583 | + .build(); | |
584 | + | |
585 | + if (checkLimits(sessionInfo, responseMsg, callback)) { | |
586 | + reportActivityInternal(sessionInfo); | |
587 | + sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(responseMsg).build(), | |
588 | + new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, TransportServiceCallback.EMPTY)); | |
589 | + } | |
566 | 590 | } |
567 | 591 | } |
568 | 592 | ... | ... |
... | ... | @@ -151,13 +151,12 @@ |
151 | 151 | </mat-form-field> |
152 | 152 | </fieldset> |
153 | 153 | <fieldset class="fields-group"> |
154 | - <legend class="group-title" translate>device-profile.lwm2m.power-mode</legend> | |
154 | + <legend class="group-title" translate>device-profile.power-saving-mode</legend> | |
155 | 155 | <mat-form-field class="mat-block" fxFlex> |
156 | 156 | <mat-label> </mat-label> |
157 | 157 | <mat-select formControlName="powerMode"> |
158 | - <mat-option *ngFor="let powerMode of powerModeLwM2MTypes" | |
159 | - [value]="powerMode"> | |
160 | - {{ powerModeLwM2MNamesMap.get(powerModeLwM2MType[powerMode]) }} | |
158 | + <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod"> | |
159 | + {{ powerModeTranslationMap.get(powerMod) | translate}} | |
161 | 160 | </mat-option> |
162 | 161 | </mat-select> |
163 | 162 | </mat-form-field> | ... | ... |
... | ... | @@ -32,7 +32,7 @@ import { |
32 | 32 | ModelValue, |
33 | 33 | ObjectLwM2M, |
34 | 34 | OBSERVE, |
35 | - OBSERVE_ATTR_TELEMETRY, powerMode, powerModeNames, | |
35 | + OBSERVE_ATTR_TELEMETRY, PowerMode, PowerModeTranslationMap, | |
36 | 36 | RESOURCES, |
37 | 37 | TELEMETRY |
38 | 38 | } from './lwm2m-profile-config.models'; |
... | ... | @@ -72,9 +72,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
72 | 72 | sortFunction: (key: string, value: object) => object; |
73 | 73 | isFwUpdateStrategy: boolean; |
74 | 74 | isSwUpdateStrategy: boolean; |
75 | - powerModeLwM2MType = powerMode; | |
76 | - powerModeLwM2MTypes = Object.keys(powerMode); | |
77 | - powerModeLwM2MNamesMap = powerModeNames; | |
75 | + powerMods = Object.values(PowerMode); | |
76 | + powerModeTranslationMap = PowerModeTranslationMap; | |
78 | 77 | |
79 | 78 | get required(): boolean { |
80 | 79 | return this.requiredValue; |
... | ... | @@ -208,7 +207,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
208 | 207 | private updateWriteValue = (value: ModelValue): void => { |
209 | 208 | const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? |
210 | 209 | this.configurationValue.clientLwM2mSettings.fwUpdateResource : ''; |
211 | - const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? | |
210 | + const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.swUpdateResource) ? | |
212 | 211 | this.configurationValue.clientLwM2mSettings.swUpdateResource : ''; |
213 | 212 | this.lwm2mDeviceProfileFormGroup.patchValue({ |
214 | 213 | objectIds: value, | ... | ... |
... | ... | @@ -128,17 +128,17 @@ export const securityConfigModeNames = new Map<securityConfigMode, string>( |
128 | 128 | ] |
129 | 129 | ); |
130 | 130 | |
131 | -export enum powerMode { | |
131 | +export enum PowerMode { | |
132 | 132 | PSM = 'PSM', |
133 | 133 | DRX = 'DRX', |
134 | 134 | E_DRX = 'E_DRX' |
135 | 135 | } |
136 | 136 | |
137 | -export const powerModeNames = new Map<powerMode, string>( | |
137 | +export const PowerModeTranslationMap = new Map<PowerMode, string>( | |
138 | 138 | [ |
139 | - [powerMode.PSM, 'Power Saving Mode (PSM)'], | |
140 | - [powerMode.DRX, 'Discontinuous Reception (DRX)'], | |
141 | - [powerMode.E_DRX, 'Extended Discontinuous Reception (eDRX)'] | |
139 | + [PowerMode.PSM, 'device-profile.power-saving-mode-type.psm'], | |
140 | + [PowerMode.DRX, 'device-profile.power-saving-mode-type.drx'], | |
141 | + [PowerMode.E_DRX, 'device-profile.power-saving-mode-type.edrx'] | |
142 | 142 | ] |
143 | 143 | ); |
144 | 144 | |
... | ... | @@ -187,7 +187,7 @@ export interface ClientLwM2mSettings { |
187 | 187 | swUpdateStrategy: number; |
188 | 188 | fwUpdateResource: string; |
189 | 189 | swUpdateResource: string; |
190 | - powerMode: powerMode; | |
190 | + powerMode: PowerMode; | |
191 | 191 | } |
192 | 192 | |
193 | 193 | export interface ObservableAttributes { |
... | ... | @@ -260,7 +260,7 @@ function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings { |
260 | 260 | swUpdateStrategy: 1, |
261 | 261 | fwUpdateResource: DEFAULT_FW_UPDATE_RESOURCE, |
262 | 262 | swUpdateResource: DEFAULT_SW_UPDATE_RESOURCE, |
263 | - powerMode: powerMode.DRX | |
263 | + powerMode: PowerMode.DRX | |
264 | 264 | }; |
265 | 265 | } |
266 | 266 | ... | ... |
... | ... | @@ -29,12 +29,12 @@ |
29 | 29 | formControlName="configuration"> |
30 | 30 | </tb-mqtt-device-transport-configuration> |
31 | 31 | </ng-template> |
32 | - <!--ng-template [ngSwitchCase]="deviceTransportType.LWM2M"> | |
32 | + <ng-template [ngSwitchCase]="deviceTransportType.LWM2M"> | |
33 | 33 | <tb-lwm2m-device-transport-configuration |
34 | 34 | [required]="required" |
35 | 35 | formControlName="configuration"> |
36 | 36 | </tb-lwm2m-device-transport-configuration> |
37 | - </ng-template--> | |
37 | + </ng-template> | |
38 | 38 | <ng-template [ngSwitchCase]="deviceTransportType.COAP"> |
39 | 39 | <tb-coap-device-transport-configuration |
40 | 40 | [required]="required" | ... | ... |
... | ... | @@ -16,9 +16,13 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <form [formGroup]="lwm2mDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;"> |
19 | - <!--tb-json-object-edit | |
20 | - [required]="required" | |
21 | - label="{{ 'device-profile.transport-type-lwm2m' | translate }}" | |
22 | - formControlName="configuration"> | |
23 | - </tb-json-object-edit--> | |
19 | + <mat-form-field class="mat-block" fxFlex> | |
20 | + <mat-label translate>device-profile.power-saving-mode</mat-label> | |
21 | + <mat-select formControlName="powerMode"> | |
22 | + <mat-option [value]="null">{{ "device-profile.power-saving-mode-type.default" | translate }}</mat-option> | |
23 | + <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod"> | |
24 | + {{ powerModeTranslationMap.get(powerMod) | translate }} | |
25 | + </mat-option> | |
26 | + </mat-select> | |
27 | + </mat-form-field> | |
24 | 28 | </form> | ... | ... |
... | ... | @@ -23,6 +23,7 @@ import { |
23 | 23 | DeviceTransportConfiguration, |
24 | 24 | DeviceTransportType, Lwm2mDeviceTransportConfiguration |
25 | 25 | } from '@shared/models/device.models'; |
26 | +import {PowerMode, PowerModeTranslationMap} from "@home/components/profile/device/lwm2m/lwm2m-profile-config.models"; | |
26 | 27 | |
27 | 28 | @Component({ |
28 | 29 | selector: 'tb-lwm2m-device-transport-configuration', |
... | ... | @@ -37,6 +38,8 @@ import { |
37 | 38 | export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit { |
38 | 39 | |
39 | 40 | lwm2mDeviceTransportConfigurationFormGroup: FormGroup; |
41 | + powerMods = Object.values(PowerMode); | |
42 | + powerModeTranslationMap = PowerModeTranslationMap; | |
40 | 43 | |
41 | 44 | private requiredValue: boolean; |
42 | 45 | get required(): boolean { |
... | ... | @@ -65,7 +68,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
65 | 68 | |
66 | 69 | ngOnInit() { |
67 | 70 | this.lwm2mDeviceTransportConfigurationFormGroup = this.fb.group({ |
68 | - configuration: [null, Validators.required] | |
71 | + powerMode: [null] | |
69 | 72 | }); |
70 | 73 | this.lwm2mDeviceTransportConfigurationFormGroup.valueChanges.subscribe(() => { |
71 | 74 | this.updateModel(); |
... | ... | @@ -82,13 +85,13 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
82 | 85 | } |
83 | 86 | |
84 | 87 | writeValue(value: Lwm2mDeviceTransportConfiguration | null): void { |
85 | - this.lwm2mDeviceTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); | |
88 | + this.lwm2mDeviceTransportConfigurationFormGroup.patchValue(value, {emitEvent: false}); | |
86 | 89 | } |
87 | 90 | |
88 | 91 | private updateModel() { |
89 | 92 | let configuration: DeviceTransportConfiguration = null; |
90 | 93 | if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { |
91 | - configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration; | |
94 | + configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue(); | |
92 | 95 | // configuration.type = DeviceTransportType.LWM2M; |
93 | 96 | } |
94 | 97 | this.propagateChange(configuration); | ... | ... |
... | ... | @@ -200,7 +200,7 @@ export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportTy |
200 | 200 | DeviceTransportType.LWM2M, |
201 | 201 | { |
202 | 202 | hasProfileConfiguration: true, |
203 | - hasDeviceConfiguration: false, | |
203 | + hasDeviceConfiguration: true, | |
204 | 204 | } |
205 | 205 | ], |
206 | 206 | [ | ... | ... |
... | ... | @@ -1213,6 +1213,13 @@ |
1213 | 1213 | "export-failed-error": "Unable to export device profile: {{error}}", |
1214 | 1214 | "device-profile-file": "Device profile file", |
1215 | 1215 | "invalid-device-profile-file-error": "Unable to import device profile: Invalid device profile data structure.", |
1216 | + "power-saving-mode": "Power Saving Mode", | |
1217 | + "power-saving-mode-type": { | |
1218 | + "default": "Use device profile power saving mode", | |
1219 | + "psm": "Power Saving Mode (PSM)", | |
1220 | + "drx": "Discontinuous Reception (DRX)", | |
1221 | + "edrx": "Extended Discontinuous Reception (eDRX)" | |
1222 | + }, | |
1216 | 1223 | "lwm2m": { |
1217 | 1224 | "object-list": "Object list", |
1218 | 1225 | "object-list-empty": "No objects selected.", | ... | ... |