diff --git a/application/src/main/data/json/system/widget_types/signal_strength.json b/application/src/main/data/json/system/widget_types/signal_strength.json index 62fc0088b6..d48b41e977 100644 --- a/application/src/main/data/json/system/widget_types/signal_strength.json +++ b/application/src/main/data/json/system/widget_types/signal_strength.json @@ -17,7 +17,7 @@ "settingsDirective": "tb-signal-strength-widget-settings", "hasBasicMode": true, "basicModeDirective": "tb-signal-strength-basic-config", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"rssi\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.2392660816082064,\"funcBody\":\"if (!prevValue) {\\n prevValue = Math.random() * -96;\\n}\\nvar value = prevValue + (Math.random() * 60 - 30);\\nif (value > 0) {\\n\\tvalue = 0;\\n} else if (value < -96) {\\n value = -96;\\n}\\nlet rand = Math.random();\\nreturn rand < 0.2 ? (rand < 0.1 ? -101 : '') : value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"layout\":\"wifi\",\"showDate\":false,\"dateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"dateFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"dateColor\":\"rgba(0, 0, 0, 0.38)\",\"activeBarsColor\":{\"color\":\"rgba(92, 223, 144, 1)\",\"type\":\"range\",\"rangeList\":[{\"to\":-85,\"color\":\"rgba(227, 71, 71, 1)\"},{\"from\":-85,\"to\":-70,\"color\":\"rgba(255, 122, 0, 1)\"},{\"from\":-70,\"to\":-55,\"color\":\"rgba(246, 206, 67, 1)\"},{\"from\":-55,\"color\":\"rgba(92, 223, 144, 1)\"}],\"colorFunction\":\"var temperature = value;\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120 * 100;\\n return tinycolor.mix('blue', 'red', percent).toHexString();\\n}\\nreturn 'blue';\"},\"inactiveBarsColor\":\"rgba(224, 224, 224, 1)\",\"showTooltip\":true,\"showTooltipValue\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0,0,0,0.76)\",\"showTooltipDate\":true,\"tooltipDateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0,0,0,0.76)\",\"tooltipBackgroundColor\":\"rgba(255,255,255,0.72)\",\"tooltipBackgroundBlur\":3,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Signal strength\",\"dropShadow\":true,\"enableFullscreen\":false,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"units\":\"dBm\",\"decimals\":0,\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"configMode\":\"basic\",\"displayTimewindow\":true,\"margin\":\"0px\",\"borderRadius\":\"0px\",\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleIcon\":\"signal_cellular_alt\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"18px\",\"timewindowStyle\":{\"showIcon\":true,\"iconSize\":\"14px\",\"icon\":\"query_builder\",\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":null,\"weight\":null,\"style\":null,\"lineHeight\":\"1\"},\"color\":null},\"titleColor\":\"rgba(0, 0, 0, 0.87)\"}" + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"rssi\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.2392660816082064,\"funcBody\":\"if (!prevValue) {\\n prevValue = Math.random() * -96;\\n}\\nvar value = prevValue + (Math.random() * 60 - 30);\\nif (value > 0) {\\n\\tvalue = 0;\\n} else if (value < -96) {\\n value = -96;\\n}\\nlet rand = Math.random();\\nreturn rand < 0.2 ? (rand < 0.1 ? -101 : '') : value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"layout\":\"wifi\",\"showDate\":false,\"dateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"dateFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"dateColor\":\"rgba(0, 0, 0, 0.38)\",\"activeBarsColor\":{\"color\":\"rgba(92, 223, 144, 1)\",\"type\":\"range\",\"rangeList\":[{\"to\":-85,\"color\":\"rgba(227, 71, 71, 1)\"},{\"from\":-85,\"to\":-70,\"color\":\"rgba(255, 122, 0, 1)\"},{\"from\":-70,\"to\":-55,\"color\":\"rgba(246, 206, 67, 1)\"},{\"from\":-55,\"color\":\"rgba(92, 223, 144, 1)\"}],\"colorFunction\":\"var temperature = value;\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120 * 100;\\n return tinycolor.mix('blue', 'red', percent).toHexString();\\n}\\nreturn 'blue';\"},\"inactiveBarsColor\":\"rgba(224, 224, 224, 1)\",\"noSignalRssiValue\":-100,\"showTooltip\":true,\"showTooltipValue\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0,0,0,0.76)\",\"showTooltipDate\":true,\"tooltipDateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0,0,0,0.76)\",\"tooltipBackgroundColor\":\"rgba(255,255,255,0.72)\",\"tooltipBackgroundBlur\":3,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Signal strength\",\"dropShadow\":true,\"enableFullscreen\":false,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"units\":\"dBm\",\"decimals\":0,\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"configMode\":\"basic\",\"displayTimewindow\":true,\"margin\":\"0px\",\"borderRadius\":\"0px\",\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleIcon\":\"signal_cellular_alt\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"18px\",\"timewindowStyle\":{\"showIcon\":true,\"iconSize\":\"14px\",\"icon\":\"query_builder\",\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":null,\"weight\":null,\"style\":null,\"lineHeight\":\"1\"},\"color\":null},\"titleColor\":\"rgba(0, 0, 0, 0.87)\"}" }, "externalId": null, "tags": [ diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java index 4ab54c0ad8..93cf5bd8c7 100644 --- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.actors.app; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.actors.ActorSystemContext; +import org.thingsboard.server.actors.ProcessFailureStrategy; import org.thingsboard.server.actors.TbActor; import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorException; @@ -88,7 +89,7 @@ public class AppActor extends ContextAwareActor { case APP_INIT_MSG: break; case PARTITION_CHANGE_MSG: - ctx.broadcastToChildren(msg); + ctx.broadcastToChildren(msg, true); break; case COMPONENT_LIFE_CYCLE_MSG: onComponentLifecycleMsg((ComponentLifecycleMsg) msg); @@ -219,6 +220,12 @@ public class AppActor extends ContextAwareActor { } } + @Override + public ProcessFailureStrategy onProcessFailure(TbActorMsg msg, Throwable t) { + log.error("Failed to process msg: {}", msg, t); + return doProcessFailure(t); + } + public static class ActorCreator extends ContextBasedCreator { public ActorCreator(ActorSystemContext context) { diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java index 6f920bc9ab..f2213c02d0 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java @@ -59,7 +59,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { } protected void initRuleChains() { - ruleChainsInitialized = true; + log.debug("[{}] Initializing rule chains", tenantId); for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { RuleChainId ruleChainId = ruleChain.getId(); log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId()); @@ -67,9 +67,11 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { visit(ruleChain, actorRef); log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId()); } + ruleChainsInitialized = true; } protected void destroyRuleChains() { + log.debug("[{}] Destroying rule chains", tenantId); for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { ctx.stop(new TbEntityActorId(ruleChain.getId())); } diff --git a/application/src/main/java/org/thingsboard/server/actors/service/ContextAwareActor.java b/application/src/main/java/org/thingsboard/server/actors/service/ContextAwareActor.java index 326411ec91..721e898708 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/ContextAwareActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/ContextAwareActor.java @@ -47,8 +47,8 @@ public abstract class ContextAwareActor extends AbstractTbActor { protected abstract boolean doProcess(TbActorMsg msg); @Override - public ProcessFailureStrategy onProcessFailure(Throwable t) { - log.debug("[{}] Processing failure: ", getActorRef().getActorId(), t); + public ProcessFailureStrategy onProcessFailure(TbActorMsg msg, Throwable t) { + log.debug("[{}] Processing failure for msg {}", getActorRef().getActorId(), msg, t); return doProcessFailure(t); } diff --git a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java index f766f8813c..dab5d05fc3 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java @@ -122,7 +122,7 @@ public class DefaultActorService extends TbApplicationEventListener> processUplinkMsg(UplinkMsg uplinkMsg) { List> result = new ArrayList<>(); try { - if (uplinkMsg.getEntityDataCount() > 0) { - for (EntityDataProto entityData : uplinkMsg.getEntityDataList()) { - result.addAll(ctx.getTelemetryProcessor().processTelemetryMsg(edge.getTenantId(), entityData)); - } - } if (uplinkMsg.getDeviceProfileUpdateMsgCount() > 0) { for (DeviceProfileUpdateMsg deviceProfileUpdateMsg : uplinkMsg.getDeviceProfileUpdateMsgList()) { result.add(((DeviceProfileProcessor) ctx.getDeviceProfileEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) @@ -731,6 +726,17 @@ public final class EdgeGrpcSession implements Closeable { .processAssetMsgFromEdge(edge.getTenantId(), edge, assetUpdateMsg)); } } + if (uplinkMsg.getEntityViewUpdateMsgCount() > 0) { + for (EntityViewUpdateMsg entityViewUpdateMsg : uplinkMsg.getEntityViewUpdateMsgList()) { + result.add(((EntityViewProcessor) ctx.getEntityViewProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) + .processEntityViewMsgFromEdge(edge.getTenantId(), edge, entityViewUpdateMsg)); + } + } + if (uplinkMsg.getEntityDataCount() > 0) { + for (EntityDataProto entityData : uplinkMsg.getEntityDataList()) { + result.addAll(ctx.getTelemetryProcessor().processTelemetryMsg(edge.getTenantId(), entityData)); + } + } if (uplinkMsg.getAlarmUpdateMsgCount() > 0) { for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdateMsgList()) { result.add(((AlarmProcessor) ctx.getAlarmEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) @@ -743,12 +749,6 @@ public final class EdgeGrpcSession implements Closeable { .processAlarmCommentMsgFromEdge(edge.getTenantId(), edge.getId(), alarmCommentUpdateMsg)); } } - if (uplinkMsg.getEntityViewUpdateMsgCount() > 0) { - for (EntityViewUpdateMsg entityViewUpdateMsg : uplinkMsg.getEntityViewUpdateMsgList()) { - result.add(((EntityViewProcessor) ctx.getEntityViewProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) - .processEntityViewMsgFromEdge(edge.getTenantId(), edge, entityViewUpdateMsg)); - } - } if (uplinkMsg.getRelationUpdateMsgCount() > 0) { for (RelationUpdateMsg relationUpdateMsg : uplinkMsg.getRelationUpdateMsgList()) { result.add(((RelationProcessor) ctx.getRelationEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) @@ -763,7 +763,8 @@ public final class EdgeGrpcSession implements Closeable { } if (uplinkMsg.getResourceUpdateMsgCount() > 0) { for (ResourceUpdateMsg resourceUpdateMsg : uplinkMsg.getResourceUpdateMsgList()) { - result.add(((ResourceProcessor) ctx.getResourceEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)).processResourceMsgFromEdge(edge.getTenantId(), edge, resourceUpdateMsg)); + result.add(((ResourceProcessor) ctx.getResourceEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) + .processResourceMsgFromEdge(edge.getTenantId(), edge, resourceUpdateMsg)); } } if (uplinkMsg.getRuleChainMetadataRequestMsgCount() > 0) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java index a3937028e4..1b96ec09bd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java @@ -47,7 +47,6 @@ public abstract class BaseAssetProfileProcessor extends BaseEdgeProcessor { assetProfile.setId(assetProfileId); assetProfile.setDefault(assetProfileById.isDefault()); } - assetProfile.setDefault(false); String assetProfileName = assetProfile.getName(); AssetProfile assetProfileByName = assetProfileService.findAssetProfileByName(tenantId, assetProfileName); if (assetProfileByName != null && !assetProfileByName.getId().equals(assetProfileId)) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java index fd4fe5ff7c..016273bef9 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java @@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.DeviceCredentials; -import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; @@ -63,13 +62,6 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor { device.setId(deviceId); } Device savedDevice = deviceService.saveDevice(device, false); - if (created) { - DeviceCredentials deviceCredentials = new DeviceCredentials(); - deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); - deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); - deviceCredentials.setCredentialsId(StringUtils.randomAlphanumeric(20)); - deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); - } tbClusterService.onDeviceUpdated(savedDevice, created ? null : device); } catch (Exception e) { log.error("[{}] Failed to process device update msg [{}]", tenantId, deviceUpdateMsg, e); @@ -91,6 +83,10 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor { tenantId, device.getName(), deviceCredentials.getCredentialsId(), deviceCredentials.getCredentialsValue()); try { DeviceCredentials deviceCredentialsByDeviceId = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, device.getId()); + if (deviceCredentialsByDeviceId == null) { + deviceCredentialsByDeviceId = new DeviceCredentials(); + deviceCredentialsByDeviceId.setDeviceId(device.getId()); + } deviceCredentialsByDeviceId.setCredentialsType(deviceCredentials.getCredentialsType()); deviceCredentialsByDeviceId.setCredentialsId(deviceCredentials.getCredentialsId()); deviceCredentialsByDeviceId.setCredentialsValue(deviceCredentials.getCredentialsValue()); @@ -111,4 +107,5 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor { protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, Device device, DeviceUpdateMsg deviceUpdateMsg); protected abstract DeviceCredentials constructDeviceCredentialsFromUpdateMsg(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg); + } diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java index 2a7cabbc00..7bb74c804c 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java @@ -156,14 +156,29 @@ public class DefaultTbActorSystem implements TbActorSystem { @Override public void broadcastToChildren(TbActorId parent, TbActorMsg msg) { - broadcastToChildren(parent, id -> true, msg); + broadcastToChildren(parent, msg, false); + } + + @Override + public void broadcastToChildren(TbActorId parent, TbActorMsg msg, boolean highPriority) { + broadcastToChildren(parent, id -> true, msg, highPriority); } @Override public void broadcastToChildren(TbActorId parent, Predicate childFilter, TbActorMsg msg) { + broadcastToChildren(parent, childFilter, msg, false); + } + + private void broadcastToChildren(TbActorId parent, Predicate childFilter, TbActorMsg msg, boolean highPriority) { Set children = parentChildMap.get(parent); if (children != null) { - children.stream().filter(childFilter).forEach(id -> tell(id, msg)); + children.stream().filter(childFilter).forEach(id -> { + try { + tell(id, msg, highPriority); + } catch (TbActorNotRegisteredException e) { + log.warn("Actor is missing for {}", id); + } + }); } } @@ -190,6 +205,8 @@ public class DefaultTbActorSystem implements TbActorSystem { stop(child); } } + parentChildMap.values().forEach(parentChildren -> parentChildren.remove(actorId)); + TbActorMailbox mailbox = actors.remove(actorId); if (mailbox != null) { mailbox.destroy(null); diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/TbActor.java b/common/actor/src/main/java/org/thingsboard/server/actors/TbActor.java index 3c0bfea49c..01ae8898ee 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/TbActor.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/TbActor.java @@ -34,7 +34,7 @@ public interface TbActor { return InitFailureStrategy.retryWithDelay(5000L * attempt); } - default ProcessFailureStrategy onProcessFailure(Throwable t) { + default ProcessFailureStrategy onProcessFailure(TbActorMsg msg, Throwable t) { if (t instanceof Error) { return ProcessFailureStrategy.stop(); } else { diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorCtx.java b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorCtx.java index 3b71daf8c2..ae3a072692 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorCtx.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorCtx.java @@ -36,6 +36,8 @@ public interface TbActorCtx extends TbActorRef { void broadcastToChildren(TbActorMsg msg); + void broadcastToChildren(TbActorMsg msg, boolean highPriority); + void broadcastToChildrenByType(TbActorMsg msg, EntityType entityType); void broadcastToChildren(TbActorMsg msg, Predicate childFilter); diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorMailbox.java b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorMailbox.java index 802fc5dccc..776d5657ce 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorMailbox.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorMailbox.java @@ -160,7 +160,7 @@ public final class TbActorMailbox implements TbActorCtx { destroy(updateException.getCause()); } catch (Throwable t) { log.debug("[{}] Failed to process message: {}", selfId, msg, t); - ProcessFailureStrategy strategy = actor.onProcessFailure(t); + ProcessFailureStrategy strategy = actor.onProcessFailure(msg, t); if (strategy.isStop()) { system.stop(selfId); } @@ -190,7 +190,12 @@ public final class TbActorMailbox implements TbActorCtx { @Override public void broadcastToChildren(TbActorMsg msg) { - system.broadcastToChildren(selfId, msg); + broadcastToChildren(msg, false); + } + + @Override + public void broadcastToChildren(TbActorMsg msg, boolean highPriority) { + system.broadcastToChildren(selfId, msg, highPriority); } @Override diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorSystem.java b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorSystem.java index 154f9d8a88..efbfdae832 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/TbActorSystem.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/TbActorSystem.java @@ -48,6 +48,8 @@ public interface TbActorSystem { void broadcastToChildren(TbActorId parent, TbActorMsg msg); + void broadcastToChildren(TbActorId parent, TbActorMsg msg, boolean highPriority); + void broadcastToChildren(TbActorId parent, Predicate childFilter, TbActorMsg msg); List filterChildren(TbActorId parent, Predicate childFilter); diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index fe0220bb7f..3c44273a62 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -35,7 +35,6 @@ import java.time.format.DateTimeParseException; import java.time.format.FormatStyle; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; -import java.util.Arrays; import java.util.Locale; import java.util.function.BiFunction; @@ -73,21 +72,37 @@ public class TbDate implements Serializable, Cloneable { instant = Instant.ofEpochMilli(dateMilliSecond); } - public TbDate(int year, int month, int date, String... tz) { + public TbDate(int year, int month, int date) { + this(year, month, date, 0, 0, 0, 0, null); + } + + public TbDate(int year, int month, int date, String tz) { this(year, month, date, 0, 0, 0, 0, tz); } - public TbDate(int year, int month, int date, int hrs, int min, String... tz) { + public TbDate(int year, int month, int date, int hrs, int min) { + this(year, month, date, hrs, min, 0, 0, null); + } + + public TbDate(int year, int month, int date, int hrs, int min, String tz) { this(year, month, date, hrs, min, 0, 0, tz); } - public TbDate(int year, int month, int date, int hrs, int min, int second, String... tz) { + public TbDate(int year, int month, int date, int hrs, int min, int second) { + this(year, month, date, hrs, min, second, 0, null); + } + + public TbDate(int year, int month, int date, int hrs, int min, int second, String tz) { this(year, month, date, hrs, min, second, 0, tz); } - public TbDate(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { - ZoneId zoneId = tz.length > 0 ? ZoneId.of(Arrays.stream(tz).findFirst().get()) : ZoneId.systemDefault(); - instant = parseInstant(year, month, date, hrs, min, second, secondMilli, zoneId); + public TbDate(int year, int month, int date, int hrs, int min, int second, int milliSecond) { + this(year, month, date, hrs, min, second, milliSecond, null); + } + + public TbDate(int year, int month, int date, int hrs, int min, int second, int milliSecond, String tz) { + ZoneId zoneId = tz != null && tz.length() > 0 ? ZoneId.of(tz) : ZoneId.systemDefault(); + instant = parseInstant(year, month, date, hrs, min, second, milliSecond, zoneId); } public Instant getInstant() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 2f7fe0680c..14d232ab89 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -163,7 +163,6 @@ public class DeviceServiceImpl extends AbstractCachedEntityService deviceService.saveDevice(device, false)) - .isInstanceOf(DataValidationException.class) - .hasMessageContaining("mock message"); - - Device deviceByName = deviceService.findDeviceByTenantIdAndName(tenantId, device.getName()); - Assertions.assertNull(deviceByName); - } - @Test public void testShouldRollbackValidatedDeviceIfDeviceCredentialsValidationFailed() { Mockito.reset(validator); diff --git a/msa/js-executor/api/jsInvokeMessageProcessor.ts b/msa/js-executor/api/jsInvokeMessageProcessor.ts index bdc63881a8..98b9c0fe0c 100644 --- a/msa/js-executor/api/jsInvokeMessageProcessor.ts +++ b/msa/js-executor/api/jsInvokeMessageProcessor.ts @@ -169,7 +169,7 @@ export class JsInvokeMessageProcessor { this.logger.info('[%s] Executing script body: [%s]', scriptId, invokeRequest.scriptBody); } if (this.executedScriptsCounter % memoryUsageTraceFrequency == 0) { - this.logger.info('Current memory usage: [%s]', process.memoryUsage()); + this.logger.info('Current memory usage: %s', JSON.stringify(process.memoryUsage())); } this.getOrCompileScript(scriptId, invokeRequest.scriptBody).then( diff --git a/ui-ngx/src/app/core/http/public-api.ts b/ui-ngx/src/app/core/http/public-api.ts index ed30742de9..8193b8917c 100644 --- a/ui-ngx/src/app/core/http/public-api.ts +++ b/ui-ngx/src/app/core/http/public-api.ts @@ -16,7 +16,9 @@ export * from './admin.service'; export * from './alarm.service'; +export * from './alarm-comment.service'; export * from './asset.service'; +export * from './asset-profile.service'; export * from './attribute.service'; export * from './audit-log.service'; export * from './component-descriptor.service'; @@ -24,12 +26,14 @@ export * from './customer.service'; export * from './dashboard.service'; export * from './device.service'; export * from './device-profile.service'; +export * from './entities-version-control.service'; export * from './entity.service'; export * from './edge.service'; export * from './entity-relation.service'; export * from './entity-view.service'; export * from './event.service'; export * from './http-utils'; +export * from './image.service'; export * from './notification.service'; export * from './oauth2.service'; export * from './ota-package.service'; diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts index 1218cedca2..609dbb8e7a 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts @@ -45,6 +45,7 @@ import { deepClone } from '@core/utils'; import { EntityType } from '@shared/models/entity-type.models'; import { fromEvent, Subscription } from 'rxjs'; import { POSITION_MAP } from '@shared/models/overlay.models'; +import { UtilsService } from '@core/services/utils.service'; export const ALARM_FILTER_CONFIG_DATA = new InjectionToken('AlarmFilterConfigData'); @@ -127,7 +128,8 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal private translate: TranslateService, private overlay: Overlay, private nativeElement: ElementRef, - private viewContainerRef: ViewContainerRef) { + private viewContainerRef: ViewContainerRef, + private utils: UtilsService) { } ngOnInit(): void { @@ -298,7 +300,7 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal this.translate.instant(alarmSeverityTranslations.get(s))).join(', ')); } if (this.alarmFilterConfig?.typeList?.length) { - filterTextParts.push(this.alarmFilterConfig.typeList.join(', ')); + filterTextParts.push(this.alarmFilterConfig.typeList.map((type) => this.customTranslate(type)).join(', ')); } if (this.alarmFilterConfig?.assignedToCurrentUser) { filterTextParts.push(this.translate.instant('alarm.assigned-to-me')); @@ -313,4 +315,8 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal } } + private customTranslate(entity: string) { + return this.utils.customTranslation(entity, entity); + } + } diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html index 96494faecd..502d80fb31 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html @@ -73,7 +73,6 @@ close
-
{{ 'widget-action.target-dashboard-state' | translate }} - {{widgetActionFormGroup.get('type').value === widgetActionType.openDashboardState ? '*' : ''}}
+
+ {{ 'widget-action.target-dashboard-state' | translate }} + * +
{ if (!dashboardId) { this.actionTypeFormGroup.get('targetDashboardStateId') @@ -400,7 +401,12 @@ export class WidgetActionComponent implements ControlValueAccessor, OnInit, Vali return []; } }), - share() + share({ + connector: () => new ReplaySubject(1), + resetOnError: false, + resetOnComplete: false, + resetOnRefCountZero: false + }) ); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.html index 6cca169f5a..9038f2a22f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.html @@ -17,49 +17,54 @@ -->
widgets.background.background-settings
-
-
-
widgets.background.background
- - - {{ backgroundTypeTranslationsMap.get(type) | translate }} - - -
- -
-
widgets.color.color
- - -
-
-
-
widgets.background.overlay
- - {{ 'widgets.background.enable-overlay' | translate }} - -
-
widgets.color.color
- - -
-
-
widgets.background.blur
- - -
px
-
+
+
+
+
widgets.background.background
+ + + {{ backgroundTypeTranslationsMap.get(type) | translate }} + + +
+ +
+
widgets.color.color
+ + +
-
-
-
- widgets.background.preview +
+
widgets.background.overlay
+ + {{ 'widgets.background.enable-overlay' | translate }} + +
+
widgets.color.color
+ + +
+
+
widgets.background.blur
+ + +
px
+
+
-
-
+
+
+ widgets.background.preview +
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.scss index 01297b9d12..6bc83fe967 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings-panel.component.scss @@ -67,6 +67,14 @@ left: 7.998px; right: 7.998px; } + .tb-background-settings-panel-content { + display: flex; + flex-direction: column; + gap: 16px; + overflow: auto; + margin: -10px; + padding: 10px; + } .tb-background-settings-panel-buttons { height: 40px; display: flex; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings.component.ts index 5ac54cbbe3..66dd774a21 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/background-settings.component.ts @@ -110,7 +110,7 @@ export class BackgroundSettingsComponent implements OnInit, ControlValueAccessor backgroundSettings: this.modelValue }; const backgroundSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, BackgroundSettingsPanelComponent, 'left', true, null, + this.viewContainerRef, BackgroundSettingsPanelComponent, ['leftOnly', 'leftTopOnly', 'leftBottomOnly'], true, null, ctx, {}, {}, {}, true); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html index 4e49d9d5c9..2270ebbddc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html @@ -62,6 +62,13 @@
+
+
widgets.signal-strength.no-signal-rssi-value
+ + + +
>( [ ['broadcastService', BroadcastService], ['deviceService', DeviceService], ['alarmService', AlarmService], + ['alarmCommentService', AlarmCommentService], ['assetService', AssetService], ['entityViewService', EntityViewService], ['customerService', CustomerService], @@ -66,6 +73,7 @@ export const ServicesMap = new Map>( ['translate', TranslateService], ['http', HttpClient], ['router', Router], + ['imageService', ImageService], ['importExport', ImportExportService], ['deviceProfileService', DeviceProfileService], ['assetProfileService', AssetProfileService], @@ -74,7 +82,11 @@ export const ServicesMap = new Map>( ['resourceService', ResourceService], ['twoFactorAuthenticationService', TwoFactorAuthenticationService], ['telemetryWsService', TelemetryWebsocketService], + ['tenantService', TenantService], + ['tenantProfileService', TenantProfileService], ['userSettingsService', UserSettingsService], + ['uiSettingsService', UiSettingsService], + ['usageInfoService', UsageInfoService], ['notificationService', NotificationService] ] ); diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index f4ae83143f..5b477d0345 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -70,6 +70,8 @@ formControlName="targets" subType="{{ ruleNotificationForm.get('triggerType').value }}" entityType="{{ entityType.NOTIFICATION_TARGET }}" + labelText="{{ 'notification.recipients' | translate }}" + requiredText="{{ 'notification.recipients-required' | translate }}" placeholderText="{{ 'notification.recipient' | translate }}">