Browse Source

Merge branch 'master' of github.com:thingsboard/thingsboard

pull/1503/head
Volodymyr Babak 8 years ago
parent
commit
37aaa81bc0
  1. 2
      application/pom.xml
  2. 5
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  3. 6
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/executors/AbstractListeningExecutor.java
  5. 48
      application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java
  6. 2
      application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java
  7. 6
      application/src/main/resources/thingsboard.yml
  8. 2
      common/data/pom.xml
  9. 2
      common/message/pom.xml
  10. 2
      common/pom.xml
  11. 2
      common/queue/pom.xml
  12. 2
      common/transport/coap/pom.xml
  13. 2
      common/transport/http/pom.xml
  14. 2
      common/transport/mqtt/pom.xml
  15. 2
      common/transport/pom.xml
  16. 2
      common/transport/transport-api/pom.xml
  17. 2
      dao/pom.xml
  18. 3
      docker/tb-js-executor.env
  19. 2
      msa/black-box-tests/pom.xml
  20. 13
      msa/js-executor/api/jsInvokeMessageProcessor.js
  21. 3
      msa/js-executor/config/custom-environment-variables.yml
  22. 3
      msa/js-executor/config/default.yml
  23. 2
      msa/js-executor/package.json
  24. 2
      msa/js-executor/pom.xml
  25. 2
      msa/pom.xml
  26. 2
      msa/tb-node/pom.xml
  27. 2
      msa/tb/pom.xml
  28. 2
      msa/transport/coap/pom.xml
  29. 2
      msa/transport/http/pom.xml
  30. 2
      msa/transport/mqtt/pom.xml
  31. 2
      msa/transport/pom.xml
  32. 2
      msa/web-ui/package.json
  33. 2
      msa/web-ui/pom.xml
  34. 4
      netty-mqtt/pom.xml
  35. 2
      pom.xml
  36. 2
      rule-engine/pom.xml
  37. 2
      rule-engine/rule-engine-api/pom.xml
  38. 4
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java
  39. 2
      rule-engine/rule-engine-components/pom.xml
  40. 11
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java
  41. 2
      tools/pom.xml
  42. 2
      transport/coap/pom.xml
  43. 2
      transport/http/pom.xml
  44. 2
      transport/mqtt/pom.xml
  45. 2
      transport/pom.xml
  46. 2
      ui/package-lock.json
  47. 2
      ui/package.json
  48. 2
      ui/pom.xml
  49. 305
      ui/src/app/locale/locale.constant-it_IT.json
  50. 12
      ui/src/app/widget/lib/map-widget2.js
  51. 2
      ui/webpack.config.prod.js

2
application/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>application</artifactId> <artifactId>application</artifactId>

5
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -67,6 +67,7 @@ import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService; import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService; import org.thingsboard.server.service.executors.ExternalCallExecutorService;
import org.thingsboard.server.service.executors.SharedEventLoopGroupService;
import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.mail.MailExecutorService;
import org.thingsboard.server.service.rpc.DeviceRpcService; import org.thingsboard.server.service.rpc.DeviceRpcService;
import org.thingsboard.server.service.script.JsExecutorService; import org.thingsboard.server.service.script.JsExecutorService;
@ -206,6 +207,10 @@ public class ActorSystemContext {
@Getter @Getter
private ExternalCallExecutorService externalCallExecutorService; private ExternalCallExecutorService externalCallExecutorService;
@Autowired
@Getter
private SharedEventLoopGroupService sharedEventLoopGroupService;
@Autowired @Autowired
@Getter @Getter
private MailService mailService; private MailService mailService;

6
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -17,6 +17,7 @@ package org.thingsboard.server.actors.ruleChain;
import akka.actor.ActorRef; import akka.actor.ActorRef;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import io.netty.channel.EventLoopGroup;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.ListeningExecutor; import org.thingsboard.rule.engine.api.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
@ -238,6 +239,11 @@ class DefaultTbContext implements TbContext {
return mainCtx.getRuleChainTransactionService(); return mainCtx.getRuleChainTransactionService();
} }
@Override
public EventLoopGroup getSharedEventLoop() {
return mainCtx.getSharedEventLoopGroupService().getSharedEventLoopGroup();
}
@Override @Override
public MailService getMailService() { public MailService getMailService() {
if (mainCtx.isAllowSystemMailService()) { if (mainCtx.isAllowSystemMailService()) {

2
application/src/main/java/org/thingsboard/server/service/executors/AbstractListeningExecutor.java

@ -34,7 +34,7 @@ public abstract class AbstractListeningExecutor implements ListeningExecutor {
@PostConstruct @PostConstruct
public void init() { public void init() {
this.service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(getThreadPollSize())); this.service = MoreExecutors.listeningDecorator(Executors.newWorkStealingPool(getThreadPollSize()));
} }
@PreDestroy @PreDestroy

48
application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2019 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.service.executors;
import com.google.common.util.concurrent.MoreExecutors;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.Getter;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Component
public class SharedEventLoopGroupService {
@Getter
private EventLoopGroup sharedEventLoopGroup;
@PostConstruct
public void init() {
this.sharedEventLoopGroup = new NioEventLoopGroup();
}
@PreDestroy
public void destroy() {
if (this.sharedEventLoopGroup != null) {
this.sharedEventLoopGroup.shutdownGracefully(0, 5, TimeUnit.SECONDS);
}
}
}

2
application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java

@ -42,7 +42,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
public void init() { public void init() {
if (useJsSandbox()) { if (useJsSandbox()) {
sandbox = NashornSandboxes.create(); sandbox = NashornSandboxes.create();
monitorExecutorService = Executors.newFixedThreadPool(getMonitorThreadPoolSize()); monitorExecutorService = Executors.newWorkStealingPool(getMonitorThreadPoolSize());
sandbox.setExecutor(monitorExecutorService); sandbox.setExecutor(monitorExecutorService);
sandbox.setMaxCPUTime(getMaxCpuTime()); sandbox.setMaxCPUTime(getMaxCpuTime());
sandbox.allowNoBraces(false); sandbox.allowNoBraces(false);

6
application/src/main/resources/thingsboard.yml

@ -200,13 +200,13 @@ actors:
# Specify thread pool size for database request callbacks executor service # Specify thread pool size for database request callbacks executor service
db_callback_thread_pool_size: "${ACTORS_RULE_DB_CALLBACK_THREAD_POOL_SIZE:1}" db_callback_thread_pool_size: "${ACTORS_RULE_DB_CALLBACK_THREAD_POOL_SIZE:1}"
# Specify thread pool size for javascript executor service # Specify thread pool size for javascript executor service
js_thread_pool_size: "${ACTORS_RULE_JS_THREAD_POOL_SIZE:10}" js_thread_pool_size: "${ACTORS_RULE_JS_THREAD_POOL_SIZE:50}"
# Specify thread pool size for mail sender executor service # Specify thread pool size for mail sender executor service
mail_thread_pool_size: "${ACTORS_RULE_MAIL_THREAD_POOL_SIZE:10}" mail_thread_pool_size: "${ACTORS_RULE_MAIL_THREAD_POOL_SIZE:50}"
# Whether to allow usage of system mail service for rules # Whether to allow usage of system mail service for rules
allow_system_mail_service: "${ACTORS_RULE_ALLOW_SYSTEM_MAIL_SERVICE:true}" allow_system_mail_service: "${ACTORS_RULE_ALLOW_SYSTEM_MAIL_SERVICE:true}"
# Specify thread pool size for external call service # Specify thread pool size for external call service
external_call_thread_pool_size: "${ACTORS_RULE_EXTERNAL_CALL_THREAD_POOL_SIZE:10}" external_call_thread_pool_size: "${ACTORS_RULE_EXTERNAL_CALL_THREAD_POOL_SIZE:50}"
chain: chain:
# Errors for particular actor are persisted once per specified amount of milliseconds # Errors for particular actor are persisted once per specified amount of milliseconds
error_persist_frequency: "${ACTORS_RULE_CHAIN_ERROR_FREQUENCY:3000}" error_persist_frequency: "${ACTORS_RULE_CHAIN_ERROR_FREQUENCY:3000}"

2
common/data/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/message/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>common</artifactId> <artifactId>common</artifactId>

2
common/queue/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common.transport</groupId> <groupId>org.thingsboard.common.transport</groupId>

2
common/transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common.transport</groupId> <groupId>org.thingsboard.common.transport</groupId>

2
common/transport/mqtt/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common.transport</groupId> <groupId>org.thingsboard.common.transport</groupId>

2
common/transport/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>common</artifactId> <artifactId>common</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>

2
common/transport/transport-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.common</groupId> <groupId>org.thingsboard.common</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.common.transport</groupId> <groupId>org.thingsboard.common.transport</groupId>

2
dao/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>dao</artifactId> <artifactId>dao</artifactId>

3
docker/tb-js-executor.env

@ -4,4 +4,5 @@ TB_KAFKA_SERVERS=kafka:9092
LOGGER_LEVEL=info LOGGER_LEVEL=info
LOG_FOLDER=logs LOG_FOLDER=logs
LOGGER_FILENAME=tb-js-executor-%DATE%.log LOGGER_FILENAME=tb-js-executor-%DATE%.log
DOCKER_MODE=true DOCKER_MODE=true
SCRIPT_BODY_TRACE_FREQUENCY=1000

2
msa/black-box-tests/pom.xml

@ -21,7 +21,7 @@
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

13
msa/js-executor/api/jsInvokeMessageProcessor.js

@ -15,16 +15,20 @@
*/ */
'use strict'; 'use strict';
const logger = require('../config/logger')('JsInvokeMessageProcessor'), const config = require('config'),
logger = require('../config/logger')('JsInvokeMessageProcessor'),
Utils = require('./utils'), Utils = require('./utils'),
js = require('./jsinvoke.proto').js, js = require('./jsinvoke.proto').js,
KeyedMessage = require('kafka-node').KeyedMessage, KeyedMessage = require('kafka-node').KeyedMessage,
JsExecutor = require('./jsExecutor'); JsExecutor = require('./jsExecutor');
const scriptBodyTraceFrequency = Number(config.get('script.script_body_trace_frequency'));
function JsInvokeMessageProcessor(producer) { function JsInvokeMessageProcessor(producer) {
this.producer = producer; this.producer = producer;
this.executor = new JsExecutor(); this.executor = new JsExecutor();
this.scriptMap = {}; this.scriptMap = {};
this.executedScriptsCounter = 0;
} }
JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) { JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) {
@ -74,6 +78,13 @@ JsInvokeMessageProcessor.prototype.processCompileRequest = function(requestId, r
JsInvokeMessageProcessor.prototype.processInvokeRequest = function(requestId, responseTopic, invokeRequest) { JsInvokeMessageProcessor.prototype.processInvokeRequest = function(requestId, responseTopic, invokeRequest) {
var scriptId = getScriptId(invokeRequest); var scriptId = getScriptId(invokeRequest);
logger.debug('[%s] Processing invoke request, scriptId: [%s]', requestId, scriptId); logger.debug('[%s] Processing invoke request, scriptId: [%s]', requestId, scriptId);
this.executedScriptsCounter++;
if ( this.executedScriptsCounter >= scriptBodyTraceFrequency ) {
this.executedScriptsCounter = 0;
if (logger.levels[logger.level] >= logger.levels['debug']) {
logger.debug('[%s] Executing script body: [%s]', scriptId, invokeRequest.scriptBody);
}
}
this.getOrCompileScript(scriptId, invokeRequest.scriptBody).then( this.getOrCompileScript(scriptId, invokeRequest.scriptBody).then(
(script) => { (script) => {
this.executor.executeScript(script, invokeRequest.args, invokeRequest.timeout).then( this.executor.executeScript(script, invokeRequest.args, invokeRequest.timeout).then(

3
msa/js-executor/config/custom-environment-variables.yml

@ -23,3 +23,6 @@ logger:
level: "LOGGER_LEVEL" level: "LOGGER_LEVEL"
path: "LOG_FOLDER" path: "LOG_FOLDER"
filename: "LOGGER_FILENAME" filename: "LOGGER_FILENAME"
script:
script_body_trace_frequency: "SCRIPT_BODY_TRACE_FREQUENCY"

3
msa/js-executor/config/default.yml

@ -24,3 +24,6 @@ logger:
level: "info" level: "info"
path: "logs" path: "logs"
filename: "tb-js-executor-%DATE%.log" filename: "tb-js-executor-%DATE%.log"
script:
script_body_trace_frequency: "1000"

2
msa/js-executor/package.json

@ -1,7 +1,7 @@
{ {
"name": "thingsboard-js-executor", "name": "thingsboard-js-executor",
"private": true, "private": true,
"version": "2.3.0", "version": "2.3.1",
"description": "ThingsBoard JavaScript Executor Microservice", "description": "ThingsBoard JavaScript Executor Microservice",
"main": "server.js", "main": "server.js",
"bin": "server.js", "bin": "server.js",

2
msa/js-executor/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

2
msa/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>

2
msa/tb-node/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

2
msa/tb/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

2
msa/transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa.transport</groupId> <groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa.transport</groupId> <groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/mqtt/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa.transport</groupId> <groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

2
msa/web-ui/package.json

@ -1,7 +1,7 @@
{ {
"name": "thingsboard-web-ui", "name": "thingsboard-web-ui",
"private": true, "private": true,
"version": "2.3.0", "version": "2.3.1",
"description": "ThingsBoard Web UI Microservice", "description": "ThingsBoard Web UI Microservice",
"main": "server.js", "main": "server.js",
"bin": "server.js", "bin": "server.js",

2
msa/web-ui/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>msa</artifactId> <artifactId>msa</artifactId>
</parent> </parent>
<groupId>org.thingsboard.msa</groupId> <groupId>org.thingsboard.msa</groupId>

4
netty-mqtt/pom.xml

@ -19,12 +19,12 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<artifactId>netty-mqtt</artifactId> <artifactId>netty-mqtt</artifactId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Netty MQTT Client</name> <name>Netty MQTT Client</name>

2
pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Thingsboard</name> <name>Thingsboard</name>

2
rule-engine/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>rule-engine</artifactId> <artifactId>rule-engine</artifactId>

2
rule-engine/rule-engine-api/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>rule-engine</artifactId> <artifactId>rule-engine</artifactId>
</parent> </parent>
<groupId>org.thingsboard.rule-engine</groupId> <groupId>org.thingsboard.rule-engine</groupId>

4
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.rule.engine.api; package org.thingsboard.rule.engine.api;
import io.netty.channel.EventLoopGroup;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -105,4 +106,7 @@ public interface TbContext {
String getNodeId(); String getNodeId();
RuleChainTransactionService getRuleChainTransactionService(); RuleChainTransactionService getRuleChainTransactionService();
EventLoopGroup getSharedEventLoop();
} }

2
rule-engine/rule-engine-components/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>rule-engine</artifactId> <artifactId>rule-engine</artifactId>
</parent> </parent>
<groupId>org.thingsboard.rule-engine</groupId> <groupId>org.thingsboard.rule-engine</groupId>

11
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java

@ -59,15 +59,13 @@ public class TbMqttNode implements TbNode {
private TbMqttNodeConfiguration config; private TbMqttNodeConfiguration config;
private EventLoopGroup eventLoopGroup;
private MqttClient mqttClient; private MqttClient mqttClient;
@Override @Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
try { try {
this.config = TbNodeUtils.convert(configuration, TbMqttNodeConfiguration.class); this.config = TbNodeUtils.convert(configuration, TbMqttNodeConfiguration.class);
this.eventLoopGroup = new NioEventLoopGroup(); this.mqttClient = initClient(ctx);
this.mqttClient = initClient();
} catch (Exception e) { } catch (Exception e) {
throw new TbNodeException(e); throw new TbNodeException(e);
} }
@ -99,12 +97,9 @@ public class TbMqttNode implements TbNode {
if (this.mqttClient != null) { if (this.mqttClient != null) {
this.mqttClient.disconnect(); this.mqttClient.disconnect();
} }
if (this.eventLoopGroup != null) {
this.eventLoopGroup.shutdownGracefully(0, 5, TimeUnit.SECONDS);
}
} }
private MqttClient initClient() throws Exception { private MqttClient initClient(TbContext ctx) throws Exception {
Optional<SslContext> sslContextOpt = initSslContext(); Optional<SslContext> sslContextOpt = initSslContext();
MqttClientConfig config = sslContextOpt.isPresent() ? new MqttClientConfig(sslContextOpt.get()) : new MqttClientConfig(); MqttClientConfig config = sslContextOpt.isPresent() ? new MqttClientConfig(sslContextOpt.get()) : new MqttClientConfig();
if (!StringUtils.isEmpty(this.config.getClientId())) { if (!StringUtils.isEmpty(this.config.getClientId())) {
@ -113,7 +108,7 @@ public class TbMqttNode implements TbNode {
config.setCleanSession(this.config.isCleanSession()); config.setCleanSession(this.config.isCleanSession());
this.config.getCredentials().configure(config); this.config.getCredentials().configure(config);
MqttClient client = MqttClient.create(config, null); MqttClient client = MqttClient.create(config, null);
client.setEventLoop(this.eventLoopGroup); client.setEventLoop(ctx.getSharedEventLoop());
Future<MqttConnectResult> connectFuture = client.connect(this.config.getHost(), this.config.getPort()); Future<MqttConnectResult> connectFuture = client.connect(this.config.getHost(), this.config.getPort());
MqttConnectResult result; MqttConnectResult result;
try { try {

2
tools/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>tools</artifactId> <artifactId>tools</artifactId>

2
transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.transport</groupId> <groupId>org.thingsboard.transport</groupId>

2
transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.transport</groupId> <groupId>org.thingsboard.transport</groupId>

2
transport/mqtt/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
</parent> </parent>
<groupId>org.thingsboard.transport</groupId> <groupId>org.thingsboard.transport</groupId>

2
transport/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>

2
ui/package-lock.json

@ -1,6 +1,6 @@
{ {
"name": "thingsboard", "name": "thingsboard",
"version": "2.3.0", "version": "2.3.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

2
ui/package.json

@ -1,7 +1,7 @@
{ {
"name": "thingsboard", "name": "thingsboard",
"private": true, "private": true,
"version": "2.3.0", "version": "2.3.1",
"description": "ThingsBoard UI", "description": "ThingsBoard UI",
"licenses": [ "licenses": [
{ {

2
ui/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>
<version>2.3.0</version> <version>2.3.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId> <artifactId>thingsboard</artifactId>
</parent> </parent>
<groupId>org.thingsboard</groupId> <groupId>org.thingsboard</groupId>

305
ui/src/app/locale/locale.constant-it_IT.json

@ -133,8 +133,13 @@
"min-polling-interval-message": "L'intervallo di polling deve essere di almeno 1 sec.", "min-polling-interval-message": "L'intervallo di polling deve essere di almeno 1 sec.",
"aknowledge-alarms-title": "Conferma { count, plural, 1 {1 allarme} other {# allarmi} }", "aknowledge-alarms-title": "Conferma { count, plural, 1 {1 allarme} other {# allarmi} }",
"aknowledge-alarms-text": "Sei sicuro di voler confermare { count, plural, 1 {1 allarme} other {# allarmi} }?", "aknowledge-alarms-text": "Sei sicuro di voler confermare { count, plural, 1 {1 allarme} other {# allarmi} }?",
"aknowledge-alarm-title": "Conferma allarme",
"aknowledge-alarm-text": "Sei sicuro di voler confermare l'allarme?",
"clear-alarms-title": "Elimina { count, plural, 1 {1 allarme} other {# allarmi} }", "clear-alarms-title": "Elimina { count, plural, 1 {1 allarme} other {# allarmi} }",
"clear-alarms-text": "Sei sicuro di voler eliminare { count, plural, 1 {1 allarme} other {# allarmi} }?" "clear-alarms-text": "Sei sicuro di voler eliminare { count, plural, 1 {1 allarme} other {# allarmi} }?",
"clear-alarm-title": "Elimina allarme",
"clear-alarm-text": "Sei sicuro di voler eliminare l'allarme?",
"alarm-status-filter": "Filtro stato allarme"
}, },
"alias": { "alias": {
"add": "Aggiungi alias", "add": "Aggiungi alias",
@ -145,7 +150,7 @@
"filter-type-single-entity": "Singola entità", "filter-type-single-entity": "Singola entità",
"filter-type-entity-list": "Lista Entità", "filter-type-entity-list": "Lista Entità",
"filter-type-entity-name": "Nome Entità", "filter-type-entity-name": "Nome Entità",
"filter-type-state-entity": "Entity from dashboard state", "filter-type-state-entity": "Entità dallo stato della dashboard",
"filter-type-state-entity-description": "Entità prelevata dai parametri di stato della dashboard", "filter-type-state-entity-description": "Entità prelevata dai parametri di stato della dashboard",
"filter-type-asset-type": "Tipo di Asset", "filter-type-asset-type": "Tipo di Asset",
"filter-type-asset-type-description": "Asset di tipo '{{assetType}}'", "filter-type-asset-type-description": "Asset di tipo '{{assetType}}'",
@ -153,26 +158,31 @@
"filter-type-device-type": "Tipo di dispositivo", "filter-type-device-type": "Tipo di dispositivo",
"filter-type-device-type-description": "Dispositivi di tipo '{{deviceType}}'", "filter-type-device-type-description": "Dispositivi di tipo '{{deviceType}}'",
"filter-type-device-type-and-name-description": "Dispositivi di tipo '{{deviceType}}' e con un nome che inizia per '{{prefix}}'", "filter-type-device-type-and-name-description": "Dispositivi di tipo '{{deviceType}}' e con un nome che inizia per '{{prefix}}'",
"filter-type-relations-query": "Relations query", "filter-type-entity-view-type": "Tipo vista entità",
"filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", "filter-type-entity-view-type-description": "Viste entità di tipo '{{entityView}}'",
"filter-type-entity-view-type-and-name-description": "Viste entità di tipo '{{entityView}}' e con un nome che inizia per '{{prefix}}'",
"filter-type-relations-query": "Query relazioni",
"filter-type-relations-query-description": "{{entities}} che hanno una relazione {{relationType}} {{direction}} {{rootEntity}}",
"filter-type-asset-search-query": "Query ricerca asset", "filter-type-asset-search-query": "Query ricerca asset",
"filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", "filter-type-asset-search-query-description": "Asset di tipo {{assetTypes}} che hanno una relazione {{relationType}} {{direction}} {{rootEntity}}",
"filter-type-device-search-query": "Query ricerca dispositivo", "filter-type-device-search-query": "Query ricerca dispositivo",
"filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", "filter-type-device-search-query-description": "Dispositivi di tipo {{deviceTypes}} che hanno una relazione {{relationType}} {{direction}} {{rootEntity}}",
"filter-type-entity-view-search-query": "Query ricerca Vista entità",
"filter-type-entity-view-search-query-description": "Viste entità di tipo {{entityViewTypes}} che hanno una relazione {{relationType}} {{direction}} {{rootEntity}}",
"entity-filter": "Filtro entità", "entity-filter": "Filtro entità",
"resolve-multiple": "Resolve as multiple entities", "resolve-multiple": "Risolvi come entità multiple",
"filter-type": "Tipo di filtro", "filter-type": "Tipo di filtro",
"filter-type-required": "Tipo di filtro richiesto.", "filter-type-required": "Tipo di filtro richiesto.",
"entity-filter-no-entity-matched": "Nessuna entità corrispondente al filtro specificato è stata trovata.", "entity-filter-no-entity-matched": "Nessuna entità corrispondente al filtro specificato è stata trovata.",
"no-entity-filter-specified": "Nessun filtro di entità specificato", "no-entity-filter-specified": "Nessun filtro di entità specificato",
"root-state-entity": "Use dashboard state entity as root", "root-state-entity": "Usa l'entità di stato della dashboard come radice",
"root-entity": "Entità radice", "root-entity": "Entità radice",
"state-entity-parameter-name": "State entity parameter name", "state-entity-parameter-name": "Nome parametro entità di stato",
"default-state-entity": "Default state entity", "default-state-entity": "Entità di stato predefinita",
"default-entity-parameter-name": "By default", "default-entity-parameter-name": "Predefinito",
"max-relation-level": "Max relation level", "max-relation-level": "Massimo livello relazione",
"unlimited-level": "Unlimited level", "unlimited-level": "Illimitato",
"state-entity": "Dashboard state entity", "state-entity": "Entità di stato della dashboard",
"all-entities": "Tutte le entità", "all-entities": "Tutte le entità",
"any-relation": "qualsiasi" "any-relation": "qualsiasi"
}, },
@ -212,10 +222,10 @@
"add-asset-text": "Aggiungi un nuovo asset", "add-asset-text": "Aggiungi un nuovo asset",
"asset-details": "Dettagli Asset", "asset-details": "Dettagli Asset",
"assign-assets": "Assegna asset", "assign-assets": "Assegna asset",
"assign-assets-text": "Assegna { count, plural, 1 {1 asset} other {# assets} } al cliente", "assign-assets-text": "Assegna { count, plural, 1 {1 asset} other {# asset} } al cliente",
"delete-assets": "Cancella asset", "delete-assets": "Cancella asset",
"unassign-assets": "Annulla assegnazione asset", "unassign-assets": "Annulla assegnazione asset",
"unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", "unassign-assets-action-title": "Annulla assegnazione { count, plural, 1 {1 asset} other {# asset} } al cliente",
"assign-new-asset": "Assegna un nuovo asset", "assign-new-asset": "Assegna un nuovo asset",
"delete-asset-title": "Sei sicuro di voler cancellare l'asset '{{assetName}}'?", "delete-asset-title": "Sei sicuro di voler cancellare l'asset '{{assetName}}'?",
"delete-asset-text": "Attenzione, dopo la conferma l'asset e tutti i relativi dati non saranno più recuperabili.", "delete-asset-text": "Attenzione, dopo la conferma l'asset e tutti i relativi dati non saranno più recuperabili.",
@ -234,7 +244,7 @@
"copyId": "Copia Id asset", "copyId": "Copia Id asset",
"idCopiedMessage": "Id Asset copiato negli Appunti", "idCopiedMessage": "Id Asset copiato negli Appunti",
"select-asset": "Seleziona asset", "select-asset": "Seleziona asset",
"no-assets-matching": "Nessun asset corrispondente a '{{entity}}' é stato trovato.", "no-assets-matching": "Nessun asset corrispondente a '{{entity}}' è stato trovato.",
"asset-required": "Asset obbligatorio", "asset-required": "Asset obbligatorio",
"name-starts-with": "Asset con nome che inizia per" "name-starts-with": "Asset con nome che inizia per"
}, },
@ -288,12 +298,17 @@
"type-suspended": "Sospeso", "type-suspended": "Sospeso",
"type-credentials-read": "Credenziali lette", "type-credentials-read": "Credenziali lette",
"type-attributes-read": "Attributi letti", "type-attributes-read": "Attributi letti",
"status-success": "Success", "type-relation-add-or-update": "Relazione aggiornata",
"status-failure": "Failure", "type-relation-delete": "Relazione eliminata",
"type-relations-delete": "Eliminate tutte le relazioni",
"type-alarm-ack": "Confermato",
"type-alarm-clear": "Eliminato",
"status-success": "Successo",
"status-failure": "Fallito",
"audit-log-details": "Dettaglio log audit", "audit-log-details": "Dettaglio log audit",
"no-audit-logs-prompt": "Log non trovati", "no-audit-logs-prompt": "Log non trovati",
"action-data": "Action data", "action-data": "Action data",
"failure-details": "Failure details", "failure-details": "Dettagli fallimento",
"search": "Cerca log audit", "search": "Cerca log audit",
"clear-search": "Cancella ricerca" "clear-search": "Cancella ricerca"
}, },
@ -333,10 +348,12 @@
"dashboard": "Dashboard cliente", "dashboard": "Dashboard cliente",
"dashboards": "Dashboard cliente", "dashboards": "Dashboard cliente",
"devices": "Dispositivi cliente", "devices": "Dispositivi cliente",
"entity-views": "Viste entità cliente",
"assets": "Asset cliente", "assets": "Asset cliente",
"public-dashboards": "Dashboard pubbliche", "public-dashboards": "Dashboard pubbliche",
"public-devices": "Dispositivi pubblici", "public-devices": "Dispositivi pubblici",
"public-assets": "Asset pubblici", "public-assets": "Asset pubblici",
"public-entity-views": "Viste entità pubbliche",
"add": "Aggiungi cliente", "add": "Aggiungi cliente",
"delete": "Elimina cliente", "delete": "Elimina cliente",
"manage-customer-users": "Gestisci utenti cliente", "manage-customer-users": "Gestisci utenti cliente",
@ -388,14 +405,14 @@
"assign-dashboard-to-customer-text": "Seleziona le dashboard da assegnare al client", "assign-dashboard-to-customer-text": "Seleziona le dashboard da assegnare al client",
"assign-to-customer-text": "Seleziona il cliente a cui assegnare la/le dashboard", "assign-to-customer-text": "Seleziona il cliente a cui assegnare la/le dashboard",
"assign-to-customer": "Assegna al cliente", "assign-to-customer": "Assegna al cliente",
"unassign-from-customer": "Unassign from customer", "unassign-from-customer": "Annulla assegnazione al cliente",
"make-public": "Rendi pubblica la dashboard", "make-public": "Rendi pubblica la dashboard",
"make-private": "Rendi privata la dashboard", "make-private": "Rendi privata la dashboard",
"manage-assigned-customers": "Gestisci clienti assegnati", "manage-assigned-customers": "Gestisci clienti assegnati",
"assigned-customers": "Clienti assegnati", "assigned-customers": "Clienti assegnati",
"assign-to-customers": "Assegna Dashboard ai Clienti", "assign-to-customers": "Assegna Dashboard ai Clienti",
"assign-to-customers-text": "Seleziona i clienti da assegnare alla/alle dashboard", "assign-to-customers-text": "Seleziona i clienti da assegnare alla/alle dashboard",
"unassign-from-customers": "Unassign Dashboard(s) From Customers", "unassign-from-customers": "Annulla assegnazione Dashboard ai Clienti",
"unassign-from-customers-text": "Seleziona i clienti di cui annullare l'assegnazione alla/alle dashboard", "unassign-from-customers-text": "Seleziona i clienti di cui annullare l'assegnazione alla/alle dashboard",
"no-dashboards-text": "Nessuna dashboard trovata", "no-dashboards-text": "Nessuna dashboard trovata",
"no-widgets": "Nessun widget configurato", "no-widgets": "Nessun widget configurato",
@ -412,10 +429,10 @@
"assign-dashboards": "Assegna dashboard", "assign-dashboards": "Assegna dashboard",
"assign-new-dashboard": "Assegna nuova dashboard", "assign-new-dashboard": "Assegna nuova dashboard",
"assign-dashboards-text": "Assegna { count, plural, 1 {1 dashboard} other {# dashboard} } ai clienti", "assign-dashboards-text": "Assegna { count, plural, 1 {1 dashboard} other {# dashboard} } ai clienti",
"unassign-dashboards-action-text": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboards} } ai clienti", "unassign-dashboards-action-text": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboard} } ai clienti",
"delete-dashboards": "Elimina dashboard", "delete-dashboards": "Elimina dashboard",
"unassign-dashboards": "Annulla assegnazione dashboard", "unassign-dashboards": "Annulla assegnazione dashboard",
"unassign-dashboards-action-title": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboards} } al cliente", "unassign-dashboards-action-title": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboard} } al cliente",
"delete-dashboard-title": "Sei sicuro di voler cancellare la dashboard '{{dashboardTitle}}'?", "delete-dashboard-title": "Sei sicuro di voler cancellare la dashboard '{{dashboardTitle}}'?",
"delete-dashboard-text": "Attenzione, dopo la conferma la dashboard e tutti i suoi dati non saranno più recuperabili.", "delete-dashboard-text": "Attenzione, dopo la conferma la dashboard e tutti i suoi dati non saranno più recuperabili.",
"delete-dashboards-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 dashboard} other {# dashboard} }?", "delete-dashboards-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 dashboard} other {# dashboard} }?",
@ -425,7 +442,7 @@
"unassign-dashboard-text": "Dopo la conferma sarà annullata l'assegnazione della dashboard e questa non sarà più accessibile dal cliente.", "unassign-dashboard-text": "Dopo la conferma sarà annullata l'assegnazione della dashboard e questa non sarà più accessibile dal cliente.",
"unassign-dashboard": "Annulla assegnazione dashboard", "unassign-dashboard": "Annulla assegnazione dashboard",
"unassign-dashboards-title": "Sei sicuro di voler annullare l'assegnazione di { count, plural, 1 {1 dashboard} other {# dashboard} }?", "unassign-dashboards-title": "Sei sicuro di voler annullare l'assegnazione di { count, plural, 1 {1 dashboard} other {# dashboard} }?",
"unassign-dashboards-text": "Dopo la conferma sarà annullata l'assegnazione di tutte le dashboards selezionate e queste non saranno più accessibili dal cliente.", "unassign-dashboards-text": "Dopo la conferma sarà annullata l'assegnazione di tutte le dashboard selezionate e queste non saranno più accessibili dal cliente.",
"public-dashboard-title": "La Dashboard è ora pubblica", "public-dashboard-title": "La Dashboard è ora pubblica",
"public-dashboard-text": "La dashboard <b>{{dashboardTitle}}</b> è ora pubblica e accessibile al <a href='{{publicLink}}' target='_blank'>link</a>:", "public-dashboard-text": "La dashboard <b>{{dashboardTitle}}</b> è ora pubblica e accessibile al <a href='{{publicLink}}' target='_blank'>link</a>:",
"public-dashboard-notice": "<b>Nota:</b> Ricorda di rendere pubblici i relativi dispositivi per accedere ai loro dati.", "public-dashboard-notice": "<b>Nota:</b> Ricorda di rendere pubblici i relativi dispositivi per accedere ai loro dati.",
@ -461,12 +478,12 @@
"vertical-margin-required": "Margine verticale obbligatorio.", "vertical-margin-required": "Margine verticale obbligatorio.",
"min-vertical-margin-message": "Ammesso un margine verticale minimo pari a 0.", "min-vertical-margin-message": "Ammesso un margine verticale minimo pari a 0.",
"max-vertical-margin-message": "Ammesso un margine verticale massimo pari a 50.", "max-vertical-margin-message": "Ammesso un margine verticale massimo pari a 50.",
"autofill-height": "Auto fill layout height", "autofill-height": "Riempi automaticamente altezza layout",
"mobile-layout": "Impostazioni layout mobile", "mobile-layout": "Impostazioni layout mobile",
"mobile-row-height": "Mobile row height, px", "mobile-row-height": "Altezza riga mobile (px)",
"mobile-row-height-required": "Mobile row height value is required.", "mobile-row-height-required": "Altezza riga mobile è richiesta.",
"min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", "min-mobile-row-height-message": "5 pixel è il minimo concesso al valore altezza riga mobile.",
"max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", "max-mobile-row-height-message": "200 pixel è il massimo concesso al valore altezza riga mobile.",
"display-title": "Mostra titolo dashboard", "display-title": "Mostra titolo dashboard",
"toolbar-always-open": "Mantieni aperta la barra degli strumenti", "toolbar-always-open": "Mantieni aperta la barra degli strumenti",
"title-color": "Colore titolo", "title-color": "Colore titolo",
@ -527,18 +544,23 @@
"units": "Simbolo speciale da mostrare accanto al valore", "units": "Simbolo speciale da mostrare accanto al valore",
"decimals": "Numero cifre decimali", "decimals": "Numero cifre decimali",
"data-generation-func": "Funzione generazione dati", "data-generation-func": "Funzione generazione dati",
"use-data-post-processing-func": "Use data post-processing function", "use-data-post-processing-func": "Usa funzione dopo il processamento dei dati",
"configuration": "Configurazione data key", "configuration": "Configurazione data key",
"timeseries": "Serie temporali", "timeseries": "Serie temporali",
"attributes": "Attributi", "attributes": "Attributi",
"alarm": "Campi allarme", "alarm": "Campi allarme",
"timeseries-required": "Entity timeseries are required.", "timeseries-required": "Le serie temporali dell'entità sono richieste.",
"timeseries-or-attributes-required": "Entity timeseries/attributes are required.", "timeseries-or-attributes-required": "Le serie temporali o gli attributi dell'entità sono richiesti.",
"maximum-timeseries-or-attributes": "Massimo { count, plural, 1 {1 serie temporale/attributo consentito.} other {# serie temporali/attributi consentiti.} }", "maximum-timeseries-or-attributes": "Massimo { count, plural, 1 {1 serie temporale/attributo consentito.} other {# serie temporali/attributi consentiti.} }",
"alarm-fields-required": "Campi allarme obbligatori.", "alarm-fields-required": "Campi allarme obbligatori.",
"function-types": "Tipi funzione", "function-types": "Tipi funzione",
"function-types-required": "Tipi funzione obbligatorio.", "function-types-required": "Tipi funzione obbligatorio.",
"maximum-function-types": "Massimo { count, plural, 1 {1 tipo di funzione consentito.} other {# tipi di funzione consentiti} }" "maximum-function-types": "Massimo { count, plural, 1 {1 tipo di funzione consentito.} other {# tipi di funzione consentiti} }",
"time-description": "timestamp del valore corrente;",
"value-description": "il valore corrente;",
"prev-value-description": "risultato della precedente chiamata alla funzione;",
"time-prev-description": "timestamp del valore precedente;",
"prev-orig-value-description": "valore precedente originale;"
}, },
"datasource": { "datasource": {
"type": "Tipo sorgente dati", "type": "Tipo sorgente dati",
@ -563,11 +585,11 @@
"no-keys-found": "Nessuna chiave trovata.", "no-keys-found": "Nessuna chiave trovata.",
"create-new-alias": "Creane uno nuovo!", "create-new-alias": "Creane uno nuovo!",
"create-new-key": "Creane una nuova!", "create-new-key": "Creane una nuova!",
"duplicate-alias-error": "Sono stati trovati dei duplicati dell'alias '{{alias}}'.<br>Gli alias di un dispositivo devono essere univoci all'interno della dashboard.", "duplicate-alias-error": "Sono stati trovati dei duplicati dell'alias '{{alias}}'.<br/>Gli alias di un dispositivo devono essere univoci all'interno della dashboard.",
"configure-alias": "Configura alias '{{alias}}'", "configure-alias": "Configura alias '{{alias}}'",
"no-devices-matching": "Nessun dispositivo corrispondente a '{{entity}}' é stato trovato.", "no-devices-matching": "Nessun dispositivo corrispondente a '{{entity}}' è stato trovato.",
"alias": "Alias", "alias": "Alias",
"alias-required": "Alias dispositivo richesto.", "alias-required": "Alias dispositivo richiesto.",
"remove-alias": "Rimuovi alias dispositivo", "remove-alias": "Rimuovi alias dispositivo",
"add-alias": "Aggiungi alias dispositivo", "add-alias": "Aggiungi alias dispositivo",
"name-starts-with": "Dispositivo il cui nome inizia per", "name-starts-with": "Dispositivo il cui nome inizia per",
@ -639,8 +661,8 @@
"accessTokenCopiedMessage": "Token di accesso del dispositivo copiato negli Appunti", "accessTokenCopiedMessage": "Token di accesso del dispositivo copiato negli Appunti",
"assignedToCustomer": "Assegnato al cliente", "assignedToCustomer": "Assegnato al cliente",
"unable-delete-device-alias-title": "Impossibile rimuovere l'alias del dispositivo", "unable-delete-device-alias-title": "Impossibile rimuovere l'alias del dispositivo",
"unable-delete-device-alias-text": "L'alias del dispositivo '{{deviceAlias}}' non può essere eliminato perchè utilizzato dai seguenti widget:<br/>{{widgetsList}}", "unable-delete-device-alias-text": "L'alias del dispositivo '{{deviceAlias}}' non può essere eliminato perché utilizzato dai seguenti widget:<br/>{{widgetsList}}",
"is-gateway": "E' un gateway", "is-gateway": "È un gateway",
"public": "Pubblico", "public": "Pubblico",
"device-public": "Il dispositivo è pubblico", "device-public": "Il dispositivo è pubblico",
"select-device": "Seleziona dispositivo" "select-device": "Seleziona dispositivo"
@ -659,9 +681,9 @@
"aliases": "Alias entità", "aliases": "Alias entità",
"entity-alias": "Alias entità", "entity-alias": "Alias entità",
"unable-delete-entity-alias-title": "Impossibile eliminare alias entità", "unable-delete-entity-alias-title": "Impossibile eliminare alias entità",
"unable-delete-entity-alias-text": "L'alias dell'entità '{{entityAlias}}' non può essere eliminato perchè utilizzato dai seguenti widget:<br/>{{widgetsList}}", "unable-delete-entity-alias-text": "L'alias dell'entità '{{entityAlias}}' non può essere eliminato perché utilizzato dai seguenti widget:<br/>{{widgetsList}}",
"duplicate-alias-error": "Trovato un duplicato dell'alias '{{alias}}'.<br>Gli alias dell'entità devono essere univoci all'interno della dashboard.", "duplicate-alias-error": "Trovato un duplicato dell'alias '{{alias}}'.<br/>Gli alias dell'entità devono essere univoci all'interno della dashboard.",
"missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", "missing-entity-filter-error": "Manca il filtro per l'alias '{{alias}}'.",
"configure-alias": "Configura '{{alias}}' alias", "configure-alias": "Configura '{{alias}}' alias",
"alias": "Alias", "alias": "Alias",
"alias-required": "Alias entità obbligatorio.", "alias-required": "Alias entità obbligatorio.",
@ -701,6 +723,10 @@
"type-assets": "Asset", "type-assets": "Asset",
"list-of-assets": "{ count, plural, 1 {Un asset} other {Lista di # asset} }", "list-of-assets": "{ count, plural, 1 {Un asset} other {Lista di # asset} }",
"asset-name-starts-with": "Asset i cui nomi iniziano per '{{prefix}}'", "asset-name-starts-with": "Asset i cui nomi iniziano per '{{prefix}}'",
"type-entity-view": "Vista entità",
"type-entity-views": "Viste entità",
"list-of-entity-views": "{ count, plural, 1 {Una vista entità} other {Lista di # viste entità} }",
"entity-view-name-starts-with": "Viste entità i cui nomi iniziano per '{{prefix}}'",
"type-rule": "Regola", "type-rule": "Regola",
"type-rules": "Regole", "type-rules": "Regole",
"list-of-rules": "{ count, plural, 1 {Una regola} other {Lista di # regole} }", "list-of-rules": "{ count, plural, 1 {Una regola} other {Lista di # regole} }",
@ -711,7 +737,7 @@
"plugin-name-starts-with": "Plugin i cui nomi iniziano per '{{prefix}}'", "plugin-name-starts-with": "Plugin i cui nomi iniziano per '{{prefix}}'",
"type-tenant": "Tenant", "type-tenant": "Tenant",
"type-tenants": "Tenants", "type-tenants": "Tenants",
"list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", "list-of-tenants": "{ count, plural, 1 {One tenant} other {Lista di # tenants} }",
"tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'",
"type-customer": "Cliente", "type-customer": "Cliente",
"type-customers": "Clienti", "type-customers": "Clienti",
@ -719,7 +745,7 @@
"customer-name-starts-with": "Clienti i cui nomi iniziano per '{{prefix}}'", "customer-name-starts-with": "Clienti i cui nomi iniziano per '{{prefix}}'",
"type-user": "Utente", "type-user": "Utente",
"type-users": "Utenti", "type-users": "Utenti",
"list-of-users": "{ count, plural, 1 {Un utente} other {Lista of # utenti} }", "list-of-users": "{ count, plural, 1 {Un utente} other {Lista di # utenti} }",
"user-name-starts-with": "Utenti i cui nomi iniziano per '{{prefix}}'", "user-name-starts-with": "Utenti i cui nomi iniziano per '{{prefix}}'",
"type-dashboard": "Dashboard", "type-dashboard": "Dashboard",
"type-dashboards": "Dashboard", "type-dashboards": "Dashboard",
@ -730,16 +756,117 @@
"list-of-alarms": "{ count, plural, 1 {Un allarme} other {Lista di # allarmi} }", "list-of-alarms": "{ count, plural, 1 {Un allarme} other {Lista di # allarmi} }",
"alarm-name-starts-with": "Allarmi i cui nomi iniziano per '{{prefix}}'", "alarm-name-starts-with": "Allarmi i cui nomi iniziano per '{{prefix}}'",
"type-rulechain": "Rule chain", "type-rulechain": "Rule chain",
"type-rulechains": "Rule chains", "type-rulechains": "Rule chain",
"list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", "list-of-rulechains": "{ count, plural, 1 {Una rule chain} other {Lista di # catene di regole} }",
"rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", "rulechain-name-starts-with": "Catene di regole i cui nomi iniziano per '{{prefix}}'",
"type-rulenode": "Nodo regola",
"type-rulenodes": "Nodi regola",
"list-of-rulenodes": "{ count, plural, 1 {Un nodo regola} other {Lista di # nodi regola} }",
"rulenode-name-starts-with": "Nodi regola i cui nomi iniziano per '{{prefix}}'",
"type-current-customer": "Cliente attuale", "type-current-customer": "Cliente attuale",
"search": "Ricerca entità", "search": "Ricerca entità",
"selected-entities": "{ count, plural, 1 {1 entità selezionata} other {# entità selezionate} }", "selected-entities": "{ count, plural, 1 {1 entità selezionata} other {# entità selezionate} }",
"entity-name": "Nome entità", "entity-name": "Nome entità",
"details": "Dettagli entità", "details": "Dettagli entità",
"no-entities-prompt": "Nessuna entità trovata", "no-entities-prompt": "Nessuna entità trovata",
"no-data": "Nessun dato da mostrare" "no-data": "Nessun dato da mostrare",
"columns-to-display": "Colonne da mostrare"
},
"entity-view": {
"entity-view": "Vista entità",
"entity-view-required": "Vista entità richiesta.",
"entity-views": "Viste entità",
"management": "Gestione viste entità",
"view-entity-views": "Visualizza Viste entità",
"entity-view-alias": "Alias vista entità",
"aliases": "Alias vista entità",
"no-alias-matching": "'{{alias}}' non trovato.",
"no-aliases-found": "Nessun alias trovato.",
"no-key-matching": "'{{key}}' non trovata.",
"no-keys-found": "Nessuna chiave trovata.",
"create-new-alias": "Creane uno nuovo!",
"create-new-key": "Creane una nuova!",
"duplicate-alias-error": "Sono stati trovati dei duplicati dell'alias '{{alias}}'.<br/>Gli alias di una vista entità devono essere univoci all'interno della dashboard.",
"configure-alias": "Configura alias '{{alias}}'",
"no-entity-views-matching": "Nessuna vista entità corrispondente a '{{entity}}' è stata trovato.",
"alias": "Alias",
"alias-required": "Alias vista entità richiesto.",
"remove-alias": "Rimuovi alias vista entità",
"add-alias": "Aggiungi alias vista entità",
"name-starts-with": "Vista entità il cui nome inizia per",
"entity-view-list": "Lista viste entità",
"use-entity-view-name-filter": "Usa filtro",
"entity-view-list-empty": "Nessuna vista entità selezionata.",
"entity-view-name-filter-required": "Filtro nome vista entità obbligatorio.",
"entity-view-name-filter-no-entity-view-matched": "Nessuna vista entità il cui nome inizia per '{{entity-view}}' è stata trovata.",
"add": "Aggiungi Vista entità",
"assign-to-customer": "Assegna al cliente",
"assign-entity-view-to-customer": "Assegna vista entità/viste entità al Cliente",
"assign-entity-view-to-customer-text": "Seleziona la vista entità da assegnare al cliente",
"no-entity-views-text": "Nessuna vista entità trovata",
"assign-to-customer-text": "Seleziona il cliente a cui assegnare la vista entità/le vista entità",
"entity-view-details": "Dettagli vista entità",
"add-entity-view-text": "Aggiungi nuova vista entità",
"delete": "Elimina vista entità",
"assign-entity-views": "Assegna viste entità",
"assign-entity-views-text": "Assegna { count, plural, 1 {1 vista entità} other {# viste entità} } al cliente",
"delete-entity-views": "Elimina viste entità",
"unassign-from-customer": "Annulla assegnazione al cliente",
"unassign-entity-views": "Annulla assegnazione viste entità",
"unassign-entity-views-action-title": "Annulla assegnazione { count, plural, 1 {1 vista entità} other {# viste entità} } al cliente",
"assign-new-entity-view": "Assegna nuova vista entità",
"delete-entity-view-title": "Sei sicuro di voler eliminare la vista entità '{{entity-viewName}}'?",
"delete-entity-view-text": "Attenzione, dopo la conferma la vista entità e tutti i suoi dati non saranno più recuperabili.",
"delete-entity-views-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 vista entità} other {# viste entità} }?",
"delete-entity-views-action-title": "Elimina { count, plural, 1 {1 vista entità} other {# viste entità} }",
"delete-entity-views-text": "Attenzione, dopo la conferma tutte le vista entità selezionati saranno eliminate e i relativi dati non saranno più recuperabili.",
"unassign-entity-view-title": "Sei sicuro di voler annullare l'assegnazione della vista entità '{{entity-viewName}}'?",
"unassign-entity-view-text": "Dopo la conferma sarà annullata l'assegnazione della vista entità e questa non sarà più accessibile dal cliente.",
"unassign-entity-view": "Annulla assegnazione vista entità",
"unassign-entity-views-title": "Sei sicuro di voler annullare l'assegnazione di { count, plural, 1 {1 vista entità} other {# viste entità} }?",
"unassign-entity-views-text": "Dopo la conferma sarà annullata l'assegnazione di tutte le vista entità selezionate e queste non saranno più accessibili dal cliente.",
"entity-view-type": "Tipo vista entità",
"entity-view-type-required": "Tipo vista entità obbligatorio.",
"select-entity-view-type": "Seleziona tipo vista entità",
"enter-entity-view-type": "Inserisci tipo vista entità",
"any-entity-view": "Qualsiasi vista entità",
"no-entity-view-types-matching": "Nessuna vista entità corrispondente a '{{entitySubtype}}' è stata trovata.",
"entity-view-type-list-empty": "Nessun tipo di vista entità selezionato.",
"entity-view-types": "Tipi vista entità",
"name": "Nome",
"name-required": "Nome obbligatorio.",
"description": "Descrizione",
"events": "Eventi",
"details": "Dettagli",
"copyId": "Copia Id vista entità",
"assignedToCustomer": "Assegnata al cliente",
"unable-entity-view-device-alias-title": "Impossibile rimuovere l'alias del vista entità",
"unable-entity-view-device-alias-text": "L'alias del vista entità '{{entity-viewAlias}}' non può essere eliminato perché utilizzato dai seguenti widget:<br/>{{widgetsList}}",
"select-entity-view": "Seleziona vista entità",
"make-public": "Rendi pubblica la vista entità",
"make-private": "Rendi privata la vista entità",
"start-date": "Data inizio",
"start-ts": "Ora inizio",
"end-date": "Data fine",
"end-ts": "Ora fine",
"date-limits": "Limiti temporali",
"client-attributes": "Attributi cliente",
"shared-attributes": "Attributi condivisi",
"server-attributes": "Attributi server",
"timeseries": "Serie temporali",
"client-attributes-placeholder": "Attributi cliente",
"shared-attributes-placeholder": "Attributi condivisi",
"server-attributes-placeholder": "Attributi server",
"timeseries-placeholder": "Serie temporali",
"target-entity": "Entità target",
"attributes-propagation": "Propagazione degli attributi",
"attributes-propagation-hint": "La vista entità copierà automaticamente gli attributi specificati dall'entità target ogni volta che questa vista entità sarà salvata e aggiornata. Per ragioni di performance, gli attributi dell'entità target non sono propagati alle viste entità ogni cambiamento di attributo. È possibile abilitare la propagazione automatica configurando il nodo regola \"Copia alla vista\" nella rule chain e collegando i messaggi \"Post attributes\" a \"Attributes Updated\" al nuovo nodo regola.",
"timeseries-data": "Dati delle serie temporali",
"timeseries-data-hint": "Imposta le chiavi delle serie temporali dell'entità target che saranno accessibili alla vista entità. Questi dati sono di sola lettura.",
"make-public-entity-view-title": "Sei sicuro di voler rendere pubblica la vista entità '{{entity-viewName}}'?",
"make-public-entity-view-text": "Dopo la conferma la vista entità e tutti i suoi dati saranno resi pubblici e accessibili dagli altri.",
"make-private-entity-view-title": "Sei sicuro di voler rendere privata la vista entità '{{entity-viewName}}'?",
"make-private-entity-view-text": "Dopo la conferma la vista entità e tutti i suoi dati saranno resi privati e non più accessibili da altri utenti."
}, },
"event": { "event": {
"event-type": "Tipo evento", "event-type": "Tipo evento",
@ -795,8 +922,8 @@
"token": "Token di sicurezza", "token": "Token di sicurezza",
"add-converter": "Aggiungi convertitore", "add-converter": "Aggiungi convertitore",
"add-config": "Aggiungi configurazione convertitore", "add-config": "Aggiungi configurazione convertitore",
"device-name-expression": "Device name expression", "device-name-expression": "Espressione nome dispositivo",
"device-type-expression": "Device type expression", "device-type-expression": "Espressione tipo dispositivo",
"custom": "Custom", "custom": "Custom",
"to-double": "To Double", "to-double": "To Double",
"transformer": "Transformer", "transformer": "Transformer",
@ -817,7 +944,7 @@
"credentials": "Credenziali", "credentials": "Credenziali",
"username": "Nome utente", "username": "Nome utente",
"password": "Password", "password": "Password",
"retry-interval": "Retry interval in milliseconds", "retry-interval": "Intervallo di ripetizione in millisecondi",
"anonymous": "Anonimo", "anonymous": "Anonimo",
"basic": "Basic", "basic": "Basic",
"pem": "PEM", "pem": "PEM",
@ -886,6 +1013,8 @@
"modbus-add-server": "Aggiungi server/slave", "modbus-add-server": "Aggiungi server/slave",
"modbus-add-server-prompt": "Aggiungi server/slave", "modbus-add-server-prompt": "Aggiungi server/slave",
"modbus-transport": "Transport", "modbus-transport": "Transport",
"modbus-tcp-reconnect": "Riconnessione automatica",
"modbus-rtu-over-tcp": "RTU over TCP",
"modbus-port-name": "Nome porta seriale", "modbus-port-name": "Nome porta seriale",
"modbus-encoding": "Codifica", "modbus-encoding": "Codifica",
"modbus-parity": "Parità", "modbus-parity": "Parità",
@ -1077,9 +1206,9 @@
"name-required": "Nome obbligatorio.", "name-required": "Nome obbligatorio.",
"description": "Descrizione", "description": "Descrizione",
"add": "Aggiungi Rule Chain", "add": "Aggiungi Rule Chain",
"set-root": "Make rule chain root", "set-root": "Imposta la rule chain come root",
"set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", "set-root-rulechain-title": "Sei sicuro di voler impostare la rule chain '{{ruleChainName}}' come root?",
"set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", "set-root-rulechain-text": "Dopo la conferma la rule chain diverrà root a gestirà tutti i messaggi in arrivo.",
"delete-rulechain-title": "Sei sicuro di voler eliminare la rule chain '{{ruleChainName}}'?", "delete-rulechain-title": "Sei sicuro di voler eliminare la rule chain '{{ruleChainName}}'?",
"delete-rulechain-text": "Attenzione, dopo la conferma la rule chain e tutti i dati relativi non saranno più recuperabili.", "delete-rulechain-text": "Attenzione, dopo la conferma la rule chain e tutti i dati relativi non saranno più recuperabili.",
"delete-rulechains-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 rule chain} other {# rule chain} }?", "delete-rulechains-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 rule chain} other {# rule chain} }?",
@ -1110,33 +1239,38 @@
"events": "Eventi", "events": "Eventi",
"search": "Ricerca nodi", "search": "Ricerca nodi",
"open-node-library": "Apri libreria nodi", "open-node-library": "Apri libreria nodi",
"add": "Add rule node", "add": "Aggiungi nodo regola",
"name": "Nome", "name": "Nome",
"name-required": "Nome obbligatorio.", "name-required": "Nome obbligatorio.",
"type": "Tipo", "type": "Tipo",
"description": "Descrizione", "description": "Descrizione",
"delete": "Delete rule node", "delete": "Elimina nodo regola",
"select-all-objects": "Seleziona tutti i nodi e le connessioni", "select-all-objects": "Seleziona tutti i nodi e le connessioni",
"deselect-all-objects": "Deselect all nodes and connections", "deselect-all-objects": "Deseleziona tutti i nodi e le connessioni",
"delete-selected-objects": "Cancella nodi e connessioni selezionate", "delete-selected-objects": "Cancella nodi e connessioni selezionate",
"delete-selected": "Delete selected", "delete-selected": "Elimina selezionati",
"select-all": "Seleziona tutto", "select-all": "Seleziona tutto",
"copy-selected": "Copia selezionata", "copy-selected": "Copia selezionata",
"deselect-all": "Deseleziona tutto", "deselect-all": "Deseleziona tutto",
"rulenode-details": "Rule node details", "rulenode-details": "Dettagli nodo regola",
"debug-mode": "Modalità debug", "debug-mode": "Modalità debug",
"configuration": "Configurazione", "configuration": "Configurazione",
"link": "Link", "link": "Link",
"link-details": "Rule node link details", "link-details": "Dettagli link nodo regola",
"add-link": "Aggiungi link", "add-link": "Aggiungi link",
"link-label": "Etichetta link", "link-label": "Etichetta link",
"link-label-required": "Etichetta link obbligatoria.", "link-label-required": "Etichetta link obbligatoria.",
"custom-link-label": "Custom link label", "custom-link-label": "Etichetta link personalizzata",
"custom-link-label-required": "Custom link label is required.", "custom-link-label-required": "Etichetta link personalizzata obbligatoria.",
"link-labels": "Etichette link",
"link-labels-required": "Etichette link richieste.",
"no-link-labels-found": "Nessuna etichetta link trovata.",
"no-link-label-matching": "'{{label}}' non trovata.",
"create-new-link-label": "Creane una nuova!",
"type-filter": "Filtro", "type-filter": "Filtro",
"type-filter-details": "Filter incoming messages with configured conditions", "type-filter-details": "Filtra i messaggi in arrivo con le condizioni configurate",
"type-enrichment": "Enrichment", "type-enrichment": "Enrichment",
"type-enrichment-details": "Add additional information into Message Metadata", "type-enrichment-details": "Aggiungi informazioni addizionali nei metadati del messaggio",
"type-transformation": "Transformation", "type-transformation": "Transformation",
"type-transformation-details": "Change Message payload and Metadata", "type-transformation-details": "Change Message payload and Metadata",
"type-action": "Azioni", "type-action": "Azioni",
@ -1147,12 +1281,15 @@
"type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain",
"type-input": "Input", "type-input": "Input",
"type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node",
"type-unknown": "Sconosciuto",
"type-unknown-details": "Nodo regola non trovato",
"directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.",
"ui-resources-load-error": "Failed to load configuration ui resources.", "ui-resources-load-error": "Failed to load configuration ui resources.",
"invalid-target-rulechain": "Unable to resolve target rule chain!", "invalid-target-rulechain": "Unable to resolve target rule chain!",
"test-script-function": "Test script function", "test-script-function": "Test script function",
"message": "Messaggio", "message": "Messaggio",
"message-type": "Tipo messaggio", "message-type": "Tipo messaggio",
"select-message-type": "Seleziona tipo messaggio",
"message-type-required": "Tipo messaggio obbligatorio", "message-type-required": "Tipo messaggio obbligatorio",
"metadata": "Metadata", "metadata": "Metadata",
"metadata-required": "Metadata entries can't be empty.", "metadata-required": "Metadata entries can't be empty.",
@ -1200,13 +1337,13 @@
}, },
"timewindow": { "timewindow": {
"days": "{ days, plural, 1 { giorno } other {# giorni } }", "days": "{ days, plural, 1 { giorno } other {# giorni } }",
"hours": "{ hours, plural, 0 { hour } 1 {1 ora } other {# ore } }", "hours": "{ hours, plural, 0 { ora } 1 {1 ora } other {# ore } }",
"minutes": "{ minutes, plural, 0 { minute } 1 {1 minuto } other {# minuti } }", "minutes": "{ minutes, plural, 0 { minuto } 1 {1 minuto } other {# minuti } }",
"seconds": "{ seconds, plural, 0 { second } 1 {1 secondo } other {# secondi } }", "seconds": "{ seconds, plural, 0 { secondo } 1 {1 secondo } other {# secondi } }",
"realtime": "Realtime", "realtime": "Realtime",
"history": "Cronologia", "history": "Cronologia",
"last-prefix": "ultimo", "last-prefix": "ultimo",
"period": "from {{ startTime }} to {{ endTime }}", "period": "da {{ startTime }} a {{ endTime }}",
"edit": "Modifica intervallo temporale", "edit": "Modifica intervallo temporale",
"date-range": "Intervallo date", "date-range": "Intervallo date",
"last": "Ultimo", "last": "Ultimo",
@ -1215,7 +1352,7 @@
"user": { "user": {
"user": "Utente", "user": "Utente",
"users": "Utenti", "users": "Utenti",
"customer-users": "Customer Users", "customer-users": "Utente cliente",
"tenant-admins": "Amministratori Tenant", "tenant-admins": "Amministratori Tenant",
"sys-admin": "Amministratore di sistema", "sys-admin": "Amministratore di sistema",
"tenant-admin": "Amministratore tenant", "tenant-admin": "Amministratore tenant",
@ -1232,7 +1369,7 @@
"delete-users-action-title": "Elimina { count, plural, 1 {1 utente} other {# utenti} }", "delete-users-action-title": "Elimina { count, plural, 1 {1 utente} other {# utenti} }",
"delete-users-text": "Attenzione, dopo la conferma tutti gli utenti selezionati saranno eliminati e tutti i relativi dati non saranno più recuperabili.", "delete-users-text": "Attenzione, dopo la conferma tutti gli utenti selezionati saranno eliminati e tutti i relativi dati non saranno più recuperabili.",
"activation-email-sent-message": "Email di attivazione inviata con successo!", "activation-email-sent-message": "Email di attivazione inviata con successo!",
"resend-activation": "Resend activation", "resend-activation": "Invia di nuovo attivazione",
"email": "Email", "email": "Email",
"email-required": "Email obbligatoria.", "email-required": "Email obbligatoria.",
"invalid-email-format": "Formato email non valido.", "invalid-email-format": "Formato email non valido.",
@ -1251,7 +1388,9 @@
"activation-link-text": "Per attivare l'utente utilizza il seguente <a href='{{activationLink}}' target='_blank'>link di attivazione</a> :", "activation-link-text": "Per attivare l'utente utilizza il seguente <a href='{{activationLink}}' target='_blank'>link di attivazione</a> :",
"copy-activation-link": "Copia link di attivazione", "copy-activation-link": "Copia link di attivazione",
"activation-link-copied-message": "Link di attivazione utente copiato negli appunti", "activation-link-copied-message": "Link di attivazione utente copiato negli appunti",
"details": "Dettagli" "details": "Dettagli",
"login-as-tenant-admin": "Accedi come Amministratore tenant",
"login-as-customer-user": "Accedi come Utente cliente"
}, },
"value": { "value": {
"type": "Tipo valore", "type": "Tipo valore",
@ -1274,7 +1413,7 @@
"select-widgets-bundle": "Seleziona bundle widget", "select-widgets-bundle": "Seleziona bundle widget",
"management": "Gestione widget", "management": "Gestione widget",
"editor": "Editor Widget", "editor": "Editor Widget",
"widget-type-not-found": "Problem loading widget configuration.<br>Probably associated\n widget type was removed.", "widget-type-not-found": "Problem loading widget configuration.<br/>Probably associated\n widget type was removed.",
"widget-type-load-error": "Widget non caricato a causa dei seguenti errori:", "widget-type-load-error": "Widget non caricato a causa dei seguenti errori:",
"remove": "Elimina widget", "remove": "Elimina widget",
"edit": "Modifica widget", "edit": "Modifica widget",
@ -1295,7 +1434,7 @@
"saveAs": "Salva widget come", "saveAs": "Salva widget come",
"save-widget-type-as": "Salva tipo widget come", "save-widget-type-as": "Salva tipo widget come",
"save-widget-type-as-text": "Please enter new widget title and/or select target widgets bundle", "save-widget-type-as-text": "Please enter new widget title and/or select target widgets bundle",
"toggle-fullscreen": "Toggle fullscreen", "toggle-fullscreen": "Commuta modalità schermo intero",
"run": "Esegui widget", "run": "Esegui widget",
"title": "Titolo widget", "title": "Titolo widget",
"title-required": "Titolo widget obbligatorio.", "title-required": "Titolo widget obbligatorio.",
@ -1308,7 +1447,7 @@
"tidy": "Tidy", "tidy": "Tidy",
"css": "CSS", "css": "CSS",
"settings-schema": "Impostazioni schema", "settings-schema": "Impostazioni schema",
"datakey-settings-schema": "Data key settings schema", "datakey-settings-schema": "Impostazioni Data key schema",
"javascript": "Javascript", "javascript": "Javascript",
"remove-widget-type-title": "Sei sicuro di voler rimuovere il tipo di widget '{{widgetName}}'?", "remove-widget-type-title": "Sei sicuro di voler rimuovere il tipo di widget '{{widgetName}}'?",
"remove-widget-type-text": "Dopo la conferma il tipo di widget e tutti i suoi dati non saranno più recuperabili.", "remove-widget-type-text": "Dopo la conferma il tipo di widget e tutti i suoi dati non saranno più recuperabili.",
@ -1367,7 +1506,7 @@
"general-settings": "Impostazioni generali", "general-settings": "Impostazioni generali",
"display-title": "Mostra titolo", "display-title": "Mostra titolo",
"drop-shadow": "Drop shadow", "drop-shadow": "Drop shadow",
"enable-fullscreen": "Abilita fullscreen", "enable-fullscreen": "Abilita schermo intero",
"background-color": "Colore sfondo", "background-color": "Colore sfondo",
"text-color": "Colore testo", "text-color": "Colore testo",
"padding": "Padding", "padding": "Padding",
@ -1412,7 +1551,7 @@
"export": "Esporta un tipo di widget", "export": "Esporta un tipo di widget",
"export-failed-error": "Impossibile esportare il tipo di widget: {{error}}", "export-failed-error": "Impossibile esportare il tipo di widget: {{error}}",
"create-new-widget-type": "Crea un nuovo tipo di widget", "create-new-widget-type": "Crea un nuovo tipo di widget",
"widget-type-file": "Widget type file", "widget-type-file": "File tipo di widget",
"invalid-widget-type-file-error": "Impossibile importare un tipo di widget: struttura dati del widget non valida." "invalid-widget-type-file-error": "Impossibile importare un tipo di widget: struttura dati del widget non valida."
}, },
"icon": { "icon": {
@ -1423,11 +1562,11 @@
}, },
"custom": { "custom": {
"widget-action": { "widget-action": {
"action-cell-button": "Action cell button", "action-cell-button": "Pulsante azione cella",
"row-click": "On row click", "row-click": "Click sulla riga",
"polygon-click": "On polygon click", "polygon-click": "Click sul poligono",
"marker-click": "On marker click", "marker-click": "Click sul marker",
"tooltip-tag-action": "Tooltip tag action" "tooltip-tag-action": "Azione tooltip"
} }
}, },
"language": { "language": {
@ -1436,9 +1575,9 @@
"de_DE": "Tedesco", "de_DE": "Tedesco",
"fr_FR": "Francese", "fr_FR": "Francese",
"zh_CN": "Cinese", "zh_CN": "Cinese",
"ko_KR": "Coreano",
"en_US": "Inglese", "en_US": "Inglese",
"it_IT": "Italiano", "it_IT": "Italiano",
"ko_KR": "Coreano",
"ru_RU": "Russo", "ru_RU": "Russo",
"es_ES": "Spagnolo", "es_ES": "Spagnolo",
"ja_JA": "Giapponese", "ja_JA": "Giapponese",
@ -1446,4 +1585,4 @@
"fa_IR": "Persiana" "fa_IR": "Persiana"
} }
} }
} }

12
ui/src/app/widget/lib/map-widget2.js

@ -305,12 +305,9 @@ export default class TbMapWidgetV2 {
} }
function updateLocationPolygonColor(location, color) { function updateLocationPolygonColor(location, color) {
if (!location.settings.calculatedPolygonColor || location.settings.calculatedPolygonColor !== color) { if (location.polygon && color) {
location.settings.calculatedPolygonColor = color; location.settings.calculatedPolygonColor = color;
if (location.polygon) { tbMap.map.updatePolygonColor(location.polygon, location.settings, color);
tbMap.map.updatePolygonColor(location.polygon, location.settings, color);
}
} }
} }
@ -338,10 +335,8 @@ export default class TbMapWidgetV2 {
function updateLocationStyle(location, dataMap) { function updateLocationStyle(location, dataMap) {
updateLocationLabel(location, dataMap); updateLocationLabel(location, dataMap);
var color = calculateLocationColor(location, dataMap); var color = calculateLocationColor(location, dataMap);
var polygonColor = calculateLocationPolygonColor(location, dataMap);
var image = calculateLocationMarkerImage(location, dataMap); var image = calculateLocationMarkerImage(location, dataMap);
updateLocationColor(location, color, image); updateLocationColor(location, color, image);
if (location.settings.usePolygonColorFunction) updateLocationPolygonColor(location, polygonColor);
updateLocationMarkerIcon(location, image); updateLocationMarkerIcon(location, image);
} }
@ -441,6 +436,7 @@ export default class TbMapWidgetV2 {
if (location.marker) { if (location.marker) {
updateLocationStyle(location, dataMap); updateLocationStyle(location, dataMap);
} }
} }
} }
return locationChanged; return locationChanged;
@ -456,11 +452,13 @@ export default class TbMapWidgetV2 {
locationPolygonClick(event, location); locationPolygonClick(event, location);
}, [location.dsIndex]); }, [location.dsIndex]);
tbMap.polygons.push(location.polygon); tbMap.polygons.push(location.polygon);
if (location.settings.usePolygonColorFunction) updateLocationPolygonColor(location, calculateLocationPolygonColor(location, dataMap));
} else if (polygonLatLngs.length > 0) { } else if (polygonLatLngs.length > 0) {
let prevPolygonArr = tbMap.map.getPolygonLatLngs(location.polygon); let prevPolygonArr = tbMap.map.getPolygonLatLngs(location.polygon);
if (!prevPolygonArr || !arraysEqual(prevPolygonArr, polygonLatLngs)) { if (!prevPolygonArr || !arraysEqual(prevPolygonArr, polygonLatLngs)) {
tbMap.map.setPolygonLatLngs(location.polygon, polygonLatLngs); tbMap.map.setPolygonLatLngs(location.polygon, polygonLatLngs);
} }
if (location.settings.usePolygonColorFunction) updateLocationPolygonColor(location, calculateLocationPolygonColor(location, dataMap));
} }
} }
} }

2
ui/webpack.config.prod.js

@ -96,7 +96,7 @@ module.exports = {
new CompressionPlugin({ new CompressionPlugin({
asset: "[path].gz[query]", asset: "[path].gz[query]",
algorithm: "gzip", algorithm: "gzip",
test: /\.js$|\.css$|\.svg$|\.ttf$|\.woff$|\.woff2|\.eot$\.json$/, test: /\.js$|\.css$|\.svg$|\.ttf$|\.woff$|\.woff2$|\.eot$|\.json$/,
threshold: 10240, threshold: 10240,
minRatio: 0.8 minRatio: 0.8
}), }),

Loading…
Cancel
Save