Added default edge rule chain to asset/device profiles. Added propagation of software id to edge
This commit is contained in:
parent
9da5f3cee3
commit
ab924d6e13
@ -233,6 +233,9 @@ public class ThingsboardInstallService {
|
|||||||
log.info("Upgrading ThingsBoard from version 3.4.1 to 3.4.2 ...");
|
log.info("Upgrading ThingsBoard from version 3.4.1 to 3.4.2 ...");
|
||||||
databaseEntitiesUpgradeService.upgradeDatabase("3.4.1");
|
databaseEntitiesUpgradeService.upgradeDatabase("3.4.1");
|
||||||
dataUpdateService.updateData("3.4.1");
|
dataUpdateService.updateData("3.4.1");
|
||||||
|
case "3.4.3":
|
||||||
|
log.info("Upgrading ThingsBoard from version 3.4.3 to 3.5.0 ...");
|
||||||
|
databaseEntitiesUpgradeService.upgradeDatabase("3.4.3");
|
||||||
log.info("Updating system data...");
|
log.info("Updating system data...");
|
||||||
systemDataLoaderService.updateSystemWidgets();
|
systemDataLoaderService.updateSystemWidgets();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -49,6 +49,10 @@ public class AssetProfileMsgConstructor {
|
|||||||
if (assetProfile.getImage() != null) {
|
if (assetProfile.getImage() != null) {
|
||||||
builder.setImage(ByteString.copyFrom(assetProfile.getImage().getBytes(StandardCharsets.UTF_8)));
|
builder.setImage(ByteString.copyFrom(assetProfile.getImage().getBytes(StandardCharsets.UTF_8)));
|
||||||
}
|
}
|
||||||
|
if (assetProfile.getDefaultEdgeRuleChainId() != null) {
|
||||||
|
builder.setDefaultRuleChainIdMSB(assetProfile.getDefaultEdgeRuleChainId().getId().getMostSignificantBits())
|
||||||
|
.setDefaultRuleChainIdLSB(assetProfile.getDefaultEdgeRuleChainId().getId().getLeastSignificantBits());
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,10 @@ public class DeviceMsgConstructor {
|
|||||||
builder.setFirmwareIdMSB(device.getFirmwareId().getId().getMostSignificantBits())
|
builder.setFirmwareIdMSB(device.getFirmwareId().getId().getMostSignificantBits())
|
||||||
.setFirmwareIdLSB(device.getFirmwareId().getId().getLeastSignificantBits());
|
.setFirmwareIdLSB(device.getFirmwareId().getId().getLeastSignificantBits());
|
||||||
}
|
}
|
||||||
|
if (device.getSoftwareId() != null) {
|
||||||
|
builder.setSoftwareIdMSB(device.getSoftwareId().getId().getMostSignificantBits())
|
||||||
|
.setSoftwareIdLSB(device.getSoftwareId().getId().getLeastSignificantBits());
|
||||||
|
}
|
||||||
if (conflictName != null) {
|
if (conflictName != null) {
|
||||||
builder.setConflictName(conflictName);
|
builder.setConflictName(conflictName);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,6 +65,14 @@ public class DeviceProfileMsgConstructor {
|
|||||||
builder.setFirmwareIdMSB(deviceProfile.getFirmwareId().getId().getMostSignificantBits())
|
builder.setFirmwareIdMSB(deviceProfile.getFirmwareId().getId().getMostSignificantBits())
|
||||||
.setFirmwareIdLSB(deviceProfile.getFirmwareId().getId().getLeastSignificantBits());
|
.setFirmwareIdLSB(deviceProfile.getFirmwareId().getId().getLeastSignificantBits());
|
||||||
}
|
}
|
||||||
|
if (deviceProfile.getSoftwareId() != null) {
|
||||||
|
builder.setSoftwareIdMSB(deviceProfile.getSoftwareId().getId().getMostSignificantBits())
|
||||||
|
.setSoftwareIdLSB(deviceProfile.getSoftwareId().getId().getLeastSignificantBits());
|
||||||
|
}
|
||||||
|
if (deviceProfile.getDefaultEdgeRuleChainId() != null) {
|
||||||
|
builder.setDefaultRuleChainIdMSB(deviceProfile.getDefaultEdgeRuleChainId().getId().getMostSignificantBits())
|
||||||
|
.setDefaultRuleChainIdLSB(deviceProfile.getDefaultEdgeRuleChainId().getId().getLeastSignificantBits());
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -677,6 +677,34 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
|
|||||||
log.error("Failed updating schema!!!", e);
|
log.error("Failed updating schema!!!", e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "3.4.3":
|
||||||
|
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
|
||||||
|
log.info("Updating schema ...");
|
||||||
|
if (isOldSchema(conn, 3004002)) {
|
||||||
|
try {
|
||||||
|
conn.createStatement().execute("ALTER TABLE asset_profile ADD COLUMN default_edge_rule_chain_id uuid"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.createStatement().execute("ALTER TABLE device_profile ADD COLUMN default_edge_rule_chain_id uuid"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.createStatement().execute("ALTER TABLE asset_profile ADD CONSTRAINT fk_default_edge_rule_chain_asset_profile FOREIGN KEY (default_edge_rule_chain_id) REFERENCES rule_chain(id)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.createStatement().execute("ALTER TABLE device_profile ADD CONSTRAINT fk_default_edge_rule_chain_device_profile FOREIGN KEY (default_edge_rule_chain_id) REFERENCES rule_chain(id)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3005000;");
|
||||||
|
}
|
||||||
|
log.info("Schema updated.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed updating schema!!!", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
|
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
package org.thingsboard.server.common.data;
|
package org.thingsboard.server.common.data;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
@ -28,7 +27,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
|||||||
import org.thingsboard.server.common.data.id.DashboardId;
|
import org.thingsboard.server.common.data.id.DashboardId;
|
||||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||||
import org.thingsboard.server.common.data.id.OtaPackageId;
|
import org.thingsboard.server.common.data.id.OtaPackageId;
|
||||||
import org.thingsboard.server.common.data.id.QueueId;
|
|
||||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.validation.Length;
|
import org.thingsboard.server.common.data.validation.Length;
|
||||||
@ -93,6 +91,11 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
|
|||||||
@ApiModelProperty(position = 10, value = "Reference to the software OTA package. If present, the specified package will be used as default device software. ")
|
@ApiModelProperty(position = 10, value = "Reference to the software OTA package. If present, the specified package will be used as default device software. ")
|
||||||
private OtaPackageId softwareId;
|
private OtaPackageId softwareId;
|
||||||
|
|
||||||
|
@ApiModelProperty(position = 17, value = "Reference to the edge rule chain. " +
|
||||||
|
"If present, the specified edge rule chain will be used on the edge to process all messages related to device, including telemetry, attribute updates, etc. " +
|
||||||
|
"Otherwise, the edge root rule chain will be used to process those messages.")
|
||||||
|
private RuleChainId defaultEdgeRuleChainId;
|
||||||
|
|
||||||
private DeviceProfileId externalId;
|
private DeviceProfileId externalId;
|
||||||
|
|
||||||
public DeviceProfile() {
|
public DeviceProfile() {
|
||||||
@ -117,6 +120,7 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
|
|||||||
this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
|
this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
|
||||||
this.firmwareId = deviceProfile.getFirmwareId();
|
this.firmwareId = deviceProfile.getFirmwareId();
|
||||||
this.softwareId = deviceProfile.getSoftwareId();
|
this.softwareId = deviceProfile.getSoftwareId();
|
||||||
|
this.defaultEdgeRuleChainId = deviceProfile.getDefaultEdgeRuleChainId();
|
||||||
this.externalId = deviceProfile.getExternalId();
|
this.externalId = deviceProfile.getExternalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,6 +68,11 @@ public class AssetProfile extends SearchTextBased<AssetProfileId> implements Has
|
|||||||
"Otherwise, the 'Main' queue will be used to store those messages.")
|
"Otherwise, the 'Main' queue will be used to store those messages.")
|
||||||
private String defaultQueueName;
|
private String defaultQueueName;
|
||||||
|
|
||||||
|
@ApiModelProperty(position = 13, value = "Reference to the edge rule chain. " +
|
||||||
|
"If present, the specified edge rule chain will be used on the edge to process all messages related to asset, including asset updates, telemetry, attribute updates, etc. " +
|
||||||
|
"Otherwise, the edge root rule chain will be used to process those messages.")
|
||||||
|
private RuleChainId defaultEdgeRuleChainId;
|
||||||
|
|
||||||
private AssetProfileId externalId;
|
private AssetProfileId externalId;
|
||||||
|
|
||||||
public AssetProfile() {
|
public AssetProfile() {
|
||||||
@ -88,6 +93,7 @@ public class AssetProfile extends SearchTextBased<AssetProfileId> implements Has
|
|||||||
this.defaultRuleChainId = assetProfile.getDefaultRuleChainId();
|
this.defaultRuleChainId = assetProfile.getDefaultRuleChainId();
|
||||||
this.defaultDashboardId = assetProfile.getDefaultDashboardId();
|
this.defaultDashboardId = assetProfile.getDefaultDashboardId();
|
||||||
this.defaultQueueName = assetProfile.getDefaultQueueName();
|
this.defaultQueueName = assetProfile.getDefaultQueueName();
|
||||||
|
this.defaultEdgeRuleChainId = assetProfile.getDefaultEdgeRuleChainId();
|
||||||
this.externalId = assetProfile.getExternalId();
|
this.externalId = assetProfile.getExternalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -203,6 +203,8 @@ message DeviceUpdateMsg {
|
|||||||
optional int64 firmwareIdMSB = 13;
|
optional int64 firmwareIdMSB = 13;
|
||||||
optional int64 firmwareIdLSB = 14;
|
optional int64 firmwareIdLSB = 14;
|
||||||
optional bytes deviceDataBytes = 15;
|
optional bytes deviceDataBytes = 15;
|
||||||
|
optional int64 softwareIdMSB = 16;
|
||||||
|
optional int64 softwareIdLSB = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeviceProfileUpdateMsg {
|
message DeviceProfileUpdateMsg {
|
||||||
@ -223,6 +225,10 @@ message DeviceProfileUpdateMsg {
|
|||||||
optional bytes image = 15;
|
optional bytes image = 15;
|
||||||
optional int64 firmwareIdMSB = 16;
|
optional int64 firmwareIdMSB = 16;
|
||||||
optional int64 firmwareIdLSB = 17;
|
optional int64 firmwareIdLSB = 17;
|
||||||
|
optional int64 softwareIdMSB = 18;
|
||||||
|
optional int64 softwareIdLSB = 19;
|
||||||
|
int64 defaultDashboardIdMSB = 20;
|
||||||
|
int64 defaultDashboardIdLSB = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AssetProfileUpdateMsg {
|
message AssetProfileUpdateMsg {
|
||||||
|
|||||||
@ -185,6 +185,7 @@ public class ModelConstants {
|
|||||||
public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key";
|
public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key";
|
||||||
public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id";
|
public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id";
|
||||||
public static final String DEVICE_PROFILE_SOFTWARE_ID_PROPERTY = "software_id";
|
public static final String DEVICE_PROFILE_SOFTWARE_ID_PROPERTY = "software_id";
|
||||||
|
public static final String DEVICE_PROFILE_DEFAULT_EDGE_RULE_CHAIN_ID_PROPERTY = "default_edge_rule_chain_id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asset profile constants.
|
* Asset profile constants.
|
||||||
@ -198,6 +199,7 @@ public class ModelConstants {
|
|||||||
public static final String ASSET_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id";
|
public static final String ASSET_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id";
|
||||||
public static final String ASSET_PROFILE_DEFAULT_DASHBOARD_ID_PROPERTY = "default_dashboard_id";
|
public static final String ASSET_PROFILE_DEFAULT_DASHBOARD_ID_PROPERTY = "default_dashboard_id";
|
||||||
public static final String ASSET_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name";
|
public static final String ASSET_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name";
|
||||||
|
public static final String ASSET_PROFILE_DEFAULT_EDGE_RULE_CHAIN_ID_PROPERTY = "default_edge_rule_chain_id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cassandra entityView constants.
|
* Cassandra entityView constants.
|
||||||
|
|||||||
@ -64,6 +64,9 @@ public final class AssetProfileEntity extends BaseSqlEntity<AssetProfile> implem
|
|||||||
@Column(name = ModelConstants.ASSET_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY)
|
@Column(name = ModelConstants.ASSET_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY)
|
||||||
private String defaultQueueName;
|
private String defaultQueueName;
|
||||||
|
|
||||||
|
@Column(name = ModelConstants.ASSET_PROFILE_DEFAULT_EDGE_RULE_CHAIN_ID_PROPERTY, columnDefinition = "uuid")
|
||||||
|
private UUID defaultEdgeRuleChainId;
|
||||||
|
|
||||||
@Column(name = ModelConstants.EXTERNAL_ID_PROPERTY)
|
@Column(name = ModelConstants.EXTERNAL_ID_PROPERTY)
|
||||||
private UUID externalId;
|
private UUID externalId;
|
||||||
|
|
||||||
@ -90,6 +93,9 @@ public final class AssetProfileEntity extends BaseSqlEntity<AssetProfile> implem
|
|||||||
this.defaultDashboardId = assetProfile.getDefaultDashboardId().getId();
|
this.defaultDashboardId = assetProfile.getDefaultDashboardId().getId();
|
||||||
}
|
}
|
||||||
this.defaultQueueName = assetProfile.getDefaultQueueName();
|
this.defaultQueueName = assetProfile.getDefaultQueueName();
|
||||||
|
if (assetProfile.getDefaultEdgeRuleChainId() != null) {
|
||||||
|
this.defaultEdgeRuleChainId = assetProfile.getDefaultEdgeRuleChainId().getId();
|
||||||
|
}
|
||||||
if (assetProfile.getExternalId() != null) {
|
if (assetProfile.getExternalId() != null) {
|
||||||
this.externalId = assetProfile.getExternalId().getId();
|
this.externalId = assetProfile.getExternalId().getId();
|
||||||
}
|
}
|
||||||
@ -127,6 +133,9 @@ public final class AssetProfileEntity extends BaseSqlEntity<AssetProfile> implem
|
|||||||
if (defaultDashboardId != null) {
|
if (defaultDashboardId != null) {
|
||||||
assetProfile.setDefaultDashboardId(new DashboardId(defaultDashboardId));
|
assetProfile.setDefaultDashboardId(new DashboardId(defaultDashboardId));
|
||||||
}
|
}
|
||||||
|
if (defaultEdgeRuleChainId != null) {
|
||||||
|
assetProfile.setDefaultEdgeRuleChainId(new RuleChainId(defaultEdgeRuleChainId));
|
||||||
|
}
|
||||||
if (externalId != null) {
|
if (externalId != null) {
|
||||||
assetProfile.setExternalId(new AssetProfileId(externalId));
|
assetProfile.setExternalId(new AssetProfileId(externalId));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
|
|||||||
@Column(name = ModelConstants.DEVICE_PROFILE_SOFTWARE_ID_PROPERTY)
|
@Column(name = ModelConstants.DEVICE_PROFILE_SOFTWARE_ID_PROPERTY)
|
||||||
private UUID softwareId;
|
private UUID softwareId;
|
||||||
|
|
||||||
|
@Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_EDGE_RULE_CHAIN_ID_PROPERTY, columnDefinition = "uuid")
|
||||||
|
private UUID defaultEdgeRuleChainId;
|
||||||
|
|
||||||
@Column(name = ModelConstants.EXTERNAL_ID_PROPERTY)
|
@Column(name = ModelConstants.EXTERNAL_ID_PROPERTY)
|
||||||
private UUID externalId;
|
private UUID externalId;
|
||||||
|
|
||||||
@ -140,6 +143,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
|
|||||||
if (deviceProfile.getSoftwareId() != null) {
|
if (deviceProfile.getSoftwareId() != null) {
|
||||||
this.softwareId = deviceProfile.getSoftwareId().getId();
|
this.softwareId = deviceProfile.getSoftwareId().getId();
|
||||||
}
|
}
|
||||||
|
if (deviceProfile.getDefaultEdgeRuleChainId() != null) {
|
||||||
|
this.defaultEdgeRuleChainId = deviceProfile.getDefaultEdgeRuleChainId().getId();
|
||||||
|
}
|
||||||
if (deviceProfile.getExternalId() != null) {
|
if (deviceProfile.getExternalId() != null) {
|
||||||
this.externalId = deviceProfile.getExternalId().getId();
|
this.externalId = deviceProfile.getExternalId().getId();
|
||||||
}
|
}
|
||||||
@ -189,6 +195,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
|
|||||||
if (softwareId != null) {
|
if (softwareId != null) {
|
||||||
deviceProfile.setSoftwareId(new OtaPackageId(softwareId));
|
deviceProfile.setSoftwareId(new OtaPackageId(softwareId));
|
||||||
}
|
}
|
||||||
|
if (defaultEdgeRuleChainId != null) {
|
||||||
|
deviceProfile.setDefaultEdgeRuleChainId(new RuleChainId(defaultEdgeRuleChainId));
|
||||||
|
}
|
||||||
if (externalId != null) {
|
if (externalId != null) {
|
||||||
deviceProfile.setExternalId(new DeviceProfileId(externalId));
|
deviceProfile.setExternalId(new DeviceProfileId(externalId));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -237,11 +237,13 @@ CREATE TABLE IF NOT EXISTS asset_profile (
|
|||||||
default_rule_chain_id uuid,
|
default_rule_chain_id uuid,
|
||||||
default_dashboard_id uuid,
|
default_dashboard_id uuid,
|
||||||
default_queue_name varchar(255),
|
default_queue_name varchar(255),
|
||||||
|
default_edge_rule_chain_id uuid,
|
||||||
external_id uuid,
|
external_id uuid,
|
||||||
CONSTRAINT asset_profile_name_unq_key UNIQUE (tenant_id, name),
|
CONSTRAINT asset_profile_name_unq_key UNIQUE (tenant_id, name),
|
||||||
CONSTRAINT asset_profile_external_id_unq_key UNIQUE (tenant_id, external_id),
|
CONSTRAINT asset_profile_external_id_unq_key UNIQUE (tenant_id, external_id),
|
||||||
CONSTRAINT fk_default_rule_chain_asset_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
|
CONSTRAINT fk_default_rule_chain_asset_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
|
||||||
CONSTRAINT fk_default_dashboard_asset_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id)
|
CONSTRAINT fk_default_dashboard_asset_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
|
||||||
|
CONSTRAINT fk_default_edge_rule_chain_asset_profile FOREIGN KEY (default_edge_rule_chain_id) REFERENCES rule_chain(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS asset (
|
CREATE TABLE IF NOT EXISTS asset (
|
||||||
@ -280,6 +282,7 @@ CREATE TABLE IF NOT EXISTS device_profile (
|
|||||||
default_dashboard_id uuid,
|
default_dashboard_id uuid,
|
||||||
default_queue_name varchar(255),
|
default_queue_name varchar(255),
|
||||||
provision_device_key varchar,
|
provision_device_key varchar,
|
||||||
|
default_edge_rule_chain_id uuid,
|
||||||
external_id uuid,
|
external_id uuid,
|
||||||
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
|
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
|
||||||
CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
|
CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
|
||||||
@ -287,7 +290,8 @@ CREATE TABLE IF NOT EXISTS device_profile (
|
|||||||
CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
|
CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
|
||||||
CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
|
CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
|
||||||
CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id),
|
CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id),
|
||||||
CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id)
|
CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id),
|
||||||
|
CONSTRAINT fk_default_edge_rule_chain_device_profile FOREIGN KEY (default_edge_rule_chain_id) REFERENCES rule_chain(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
DO
|
DO
|
||||||
|
|||||||
@ -58,6 +58,12 @@
|
|||||||
[queueType]="serviceType"
|
[queueType]="serviceType"
|
||||||
formControlName="defaultQueueName">
|
formControlName="defaultQueueName">
|
||||||
</tb-queue-autocomplete>
|
</tb-queue-autocomplete>
|
||||||
|
<tb-rule-chain-autocomplete
|
||||||
|
labelText="device-profile.default-edge-rule-chain"
|
||||||
|
formControlName="defaultEdgeRuleChainId"
|
||||||
|
[ruleChainType]="edgeRuleChainType">
|
||||||
|
<div tb-hint>{{'device-profile.default-edge-rule-chain-hint' | translate}}</div>
|
||||||
|
</tb-rule-chain-autocomplete>
|
||||||
<mat-form-field fxHide class="mat-block">
|
<mat-form-field fxHide class="mat-block">
|
||||||
<mat-label translate>device-profile.type</mat-label>
|
<mat-label translate>device-profile.type</mat-label>
|
||||||
<mat-select formControlName="type" required>
|
<mat-select formControlName="type" required>
|
||||||
|
|||||||
@ -50,6 +50,7 @@ import { StepperSelectionEvent } from '@angular/cdk/stepper';
|
|||||||
import { deepTrim } from '@core/utils';
|
import { deepTrim } from '@core/utils';
|
||||||
import { ServiceType } from '@shared/models/queue.models';
|
import { ServiceType } from '@shared/models/queue.models';
|
||||||
import { DashboardId } from '@shared/models/id/dashboard-id';
|
import { DashboardId } from '@shared/models/id/dashboard-id';
|
||||||
|
import { RuleChainType } from '@shared/models/rule-chain.models';
|
||||||
|
|
||||||
export interface AddDeviceProfileDialogData {
|
export interface AddDeviceProfileDialogData {
|
||||||
deviceProfileName: string;
|
deviceProfileName: string;
|
||||||
@ -93,6 +94,8 @@ export class AddDeviceProfileDialogComponent extends
|
|||||||
|
|
||||||
serviceType = ServiceType.TB_RULE_ENGINE;
|
serviceType = ServiceType.TB_RULE_ENGINE;
|
||||||
|
|
||||||
|
edgeRuleChainType = RuleChainType.EDGE;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: AddDeviceProfileDialogData,
|
@Inject(MAT_DIALOG_DATA) public data: AddDeviceProfileDialogData,
|
||||||
@ -111,6 +114,7 @@ export class AddDeviceProfileDialogComponent extends
|
|||||||
defaultRuleChainId: [null, []],
|
defaultRuleChainId: [null, []],
|
||||||
defaultDashboardId: [null, []],
|
defaultDashboardId: [null, []],
|
||||||
defaultQueueName: [null, []],
|
defaultQueueName: [null, []],
|
||||||
|
defaultEdgeRuleChainId: [null, []],
|
||||||
description: ['', []]
|
description: ['', []]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -205,6 +209,9 @@ export class AddDeviceProfileDialogComponent extends
|
|||||||
if (this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value) {
|
if (this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value) {
|
||||||
deviceProfile.defaultDashboardId = new DashboardId(this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value);
|
deviceProfile.defaultDashboardId = new DashboardId(this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value);
|
||||||
}
|
}
|
||||||
|
if (this.deviceProfileDetailsFormGroup.get('defaultEdgeRuleChainId').value) {
|
||||||
|
deviceProfile.defaultEdgeRuleChainId = new RuleChainId(this.deviceProfileDetailsFormGroup.get('defaultEdgeRuleChainId').value);
|
||||||
|
}
|
||||||
this.deviceProfileService.saveDeviceProfile(deepTrim(deviceProfile)).subscribe(
|
this.deviceProfileService.saveDeviceProfile(deepTrim(deviceProfile)).subscribe(
|
||||||
(savedDeviceProfile) => {
|
(savedDeviceProfile) => {
|
||||||
this.dialogRef.close(savedDeviceProfile);
|
this.dialogRef.close(savedDeviceProfile);
|
||||||
|
|||||||
@ -77,6 +77,12 @@
|
|||||||
[queueType]="serviceType"
|
[queueType]="serviceType"
|
||||||
formControlName="defaultQueueName">
|
formControlName="defaultQueueName">
|
||||||
</tb-queue-autocomplete>
|
</tb-queue-autocomplete>
|
||||||
|
<tb-rule-chain-autocomplete
|
||||||
|
labelText="asset-profile.default-edge-rule-chain"
|
||||||
|
formControlName="defaultEdgeRuleChainId"
|
||||||
|
[ruleChainType]="edgeRuleChainType">
|
||||||
|
<div tb-hint>{{'asset-profile.default-edge-rule-chain-hint' | translate}}</div>
|
||||||
|
</tb-rule-chain-autocomplete>
|
||||||
<tb-image-input fxFlex
|
<tb-image-input fxFlex
|
||||||
label="{{'asset-profile.image' | translate}}"
|
label="{{'asset-profile.image' | translate}}"
|
||||||
maxSizeByte="524288"
|
maxSizeByte="524288"
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import { ServiceType } from '@shared/models/queue.models';
|
|||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { DashboardId } from '@shared/models/id/dashboard-id';
|
import { DashboardId } from '@shared/models/id/dashboard-id';
|
||||||
import { AssetProfile, TB_SERVICE_QUEUE } from '@shared/models/asset.models';
|
import { AssetProfile, TB_SERVICE_QUEUE } from '@shared/models/asset.models';
|
||||||
|
import { RuleChainType } from '@shared/models/rule-chain.models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-asset-profile',
|
selector: 'tb-asset-profile',
|
||||||
@ -43,6 +44,8 @@ export class AssetProfileComponent extends EntityComponent<AssetProfile> {
|
|||||||
|
|
||||||
serviceType = ServiceType.TB_RULE_ENGINE;
|
serviceType = ServiceType.TB_RULE_ENGINE;
|
||||||
|
|
||||||
|
edgeRuleChainType = RuleChainType.EDGE;
|
||||||
|
|
||||||
TB_SERVICE_QUEUE = TB_SERVICE_QUEUE;
|
TB_SERVICE_QUEUE = TB_SERVICE_QUEUE;
|
||||||
|
|
||||||
assetProfileId: EntityId;
|
assetProfileId: EntityId;
|
||||||
@ -73,6 +76,7 @@ export class AssetProfileComponent extends EntityComponent<AssetProfile> {
|
|||||||
defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
|
defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
|
||||||
defaultDashboardId: [entity && entity.defaultDashboardId ? entity.defaultDashboardId.id : null, []],
|
defaultDashboardId: [entity && entity.defaultDashboardId ? entity.defaultDashboardId.id : null, []],
|
||||||
defaultQueueName: [entity ? entity.defaultQueueName : null, []],
|
defaultQueueName: [entity ? entity.defaultQueueName : null, []],
|
||||||
|
defaultEdgeRuleChainId: [entity && entity.defaultEdgeRuleChainId ? entity.defaultEdgeRuleChainId.id : null, []],
|
||||||
description: [entity ? entity.description : '', []],
|
description: [entity ? entity.description : '', []],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -86,6 +90,7 @@ export class AssetProfileComponent extends EntityComponent<AssetProfile> {
|
|||||||
this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
|
this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({defaultDashboardId: entity.defaultDashboardId ? entity.defaultDashboardId.id : null}, {emitEvent: false});
|
this.entityForm.patchValue({defaultDashboardId: entity.defaultDashboardId ? entity.defaultDashboardId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
|
this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
|
||||||
|
this.entityForm.patchValue({defaultEdgeRuleChainId: entity.defaultEdgeRuleChainId ? entity.defaultEdgeRuleChainId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({description: entity.description}, {emitEvent: false});
|
this.entityForm.patchValue({description: entity.description}, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +101,9 @@ export class AssetProfileComponent extends EntityComponent<AssetProfile> {
|
|||||||
if (formValue.defaultDashboardId) {
|
if (formValue.defaultDashboardId) {
|
||||||
formValue.defaultDashboardId = new DashboardId(formValue.defaultDashboardId);
|
formValue.defaultDashboardId = new DashboardId(formValue.defaultDashboardId);
|
||||||
}
|
}
|
||||||
|
if (formValue.defaultEdgeRuleChainId) {
|
||||||
|
formValue.defaultEdgeRuleChainId = new RuleChainId(formValue.defaultEdgeRuleChainId);
|
||||||
|
}
|
||||||
return super.prepareFormValue(formValue);
|
return super.prepareFormValue(formValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,12 @@
|
|||||||
[queueType]="serviceType"
|
[queueType]="serviceType"
|
||||||
formControlName="defaultQueueName">
|
formControlName="defaultQueueName">
|
||||||
</tb-queue-autocomplete>
|
</tb-queue-autocomplete>
|
||||||
|
<tb-rule-chain-autocomplete
|
||||||
|
labelText="device-profile.default-edge-rule-chain"
|
||||||
|
formControlName="defaultEdgeRuleChainId"
|
||||||
|
[ruleChainType]="edgeRuleChainType">
|
||||||
|
<div tb-hint>{{'device-profile.default-edge-rule-chain-hint' | translate}}</div>
|
||||||
|
</tb-rule-chain-autocomplete>
|
||||||
<tb-ota-package-autocomplete
|
<tb-ota-package-autocomplete
|
||||||
[useFullEntityId]="true"
|
[useFullEntityId]="true"
|
||||||
[showDetailsPageLink]="true"
|
[showDetailsPageLink]="true"
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import { ServiceType } from '@shared/models/queue.models';
|
|||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { OtaUpdateType } from '@shared/models/ota-package.models';
|
import { OtaUpdateType } from '@shared/models/ota-package.models';
|
||||||
import { DashboardId } from '@shared/models/id/dashboard-id';
|
import { DashboardId } from '@shared/models/id/dashboard-id';
|
||||||
|
import { RuleChainType } from '@shared/models/rule-chain.models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-device-profile',
|
selector: 'tb-device-profile',
|
||||||
@ -71,6 +72,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
|||||||
|
|
||||||
serviceType = ServiceType.TB_RULE_ENGINE;
|
serviceType = ServiceType.TB_RULE_ENGINE;
|
||||||
|
|
||||||
|
edgeRuleChainType = RuleChainType.EDGE;
|
||||||
|
|
||||||
deviceProfileId: EntityId;
|
deviceProfileId: EntityId;
|
||||||
|
|
||||||
otaUpdateType = OtaUpdateType;
|
otaUpdateType = OtaUpdateType;
|
||||||
@ -118,6 +121,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
|||||||
defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
|
defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
|
||||||
defaultDashboardId: [entity && entity.defaultDashboardId ? entity.defaultDashboardId.id : null, []],
|
defaultDashboardId: [entity && entity.defaultDashboardId ? entity.defaultDashboardId.id : null, []],
|
||||||
defaultQueueName: [entity ? entity.defaultQueueName : null, []],
|
defaultQueueName: [entity ? entity.defaultQueueName : null, []],
|
||||||
|
defaultEdgeRuleChainId: [entity && entity.defaultEdgeRuleChainId ? entity.defaultEdgeRuleChainId.id : null, []],
|
||||||
firmwareId: [entity ? entity.firmwareId : null],
|
firmwareId: [entity ? entity.firmwareId : null],
|
||||||
softwareId: [entity ? entity.softwareId : null],
|
softwareId: [entity ? entity.softwareId : null],
|
||||||
description: [entity ? entity.description : '', []],
|
description: [entity ? entity.description : '', []],
|
||||||
@ -198,6 +202,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
|||||||
this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
|
this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({defaultDashboardId: entity.defaultDashboardId ? entity.defaultDashboardId.id : null}, {emitEvent: false});
|
this.entityForm.patchValue({defaultDashboardId: entity.defaultDashboardId ? entity.defaultDashboardId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
|
this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
|
||||||
|
this.entityForm.patchValue({defaultEdgeRuleChainId: entity.defaultEdgeRuleChainId ? entity.defaultEdgeRuleChainId.id : null}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false});
|
this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({softwareId: entity.softwareId}, {emitEvent: false});
|
this.entityForm.patchValue({softwareId: entity.softwareId}, {emitEvent: false});
|
||||||
this.entityForm.patchValue({description: entity.description}, {emitEvent: false});
|
this.entityForm.patchValue({description: entity.description}, {emitEvent: false});
|
||||||
@ -210,6 +215,9 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
|||||||
if (formValue.defaultDashboardId) {
|
if (formValue.defaultDashboardId) {
|
||||||
formValue.defaultDashboardId = new DashboardId(formValue.defaultDashboardId);
|
formValue.defaultDashboardId = new DashboardId(formValue.defaultDashboardId);
|
||||||
}
|
}
|
||||||
|
if (formValue.defaultEdgeRuleChainId) {
|
||||||
|
formValue.defaultEdgeRuleChainId = new RuleChainId(formValue.defaultEdgeRuleChainId);
|
||||||
|
}
|
||||||
const deviceProvisionConfiguration: DeviceProvisionConfiguration = formValue.profileData.provisionConfiguration;
|
const deviceProvisionConfiguration: DeviceProvisionConfiguration = formValue.profileData.provisionConfiguration;
|
||||||
formValue.provisionType = deviceProvisionConfiguration.type;
|
formValue.provisionType = deviceProvisionConfiguration.type;
|
||||||
formValue.provisionDeviceKey = deviceProvisionConfiguration.provisionDeviceKey;
|
formValue.provisionDeviceKey = deviceProvisionConfiguration.provisionDeviceKey;
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<mat-form-field [formGroup]="selectRuleChainFormGroup" class="mat-block">
|
<mat-form-field [formGroup]="selectRuleChainFormGroup" class="mat-block">
|
||||||
<input matInput type="text" placeholder="{{ ruleChainLabel | translate }}"
|
<input matInput type="text" placeholder="{{ labelText | translate }}"
|
||||||
#ruleChainInput
|
#ruleChainInput
|
||||||
formControlName="ruleChainId"
|
formControlName="ruleChainId"
|
||||||
(focusin)="onFocus()"
|
(focusin)="onFocus()"
|
||||||
@ -54,4 +54,7 @@
|
|||||||
<mat-error *ngIf="selectRuleChainFormGroup.get('ruleChainId').hasError('required')">
|
<mat-error *ngIf="selectRuleChainFormGroup.get('ruleChainId').hasError('required')">
|
||||||
{{ 'rulechain.rulechain-required' | translate }}
|
{{ 'rulechain.rulechain-required' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
<mat-hint>
|
||||||
|
<ng-content select="[tb-hint]"></ng-content>
|
||||||
|
</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|||||||
@ -45,16 +45,17 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI
|
|||||||
|
|
||||||
selectRuleChainFormGroup: FormGroup;
|
selectRuleChainFormGroup: FormGroup;
|
||||||
|
|
||||||
ruleChainLabel = 'rulechain.rulechain';
|
|
||||||
|
|
||||||
modelValue: string | null;
|
modelValue: string | null;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
labelText: string;
|
labelText: string = 'rulechain.rulechain';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
requiredText: string;
|
requiredText: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
ruleChainType: RuleChainType = RuleChainType.CORE;
|
||||||
|
|
||||||
private requiredValue: boolean;
|
private requiredValue: boolean;
|
||||||
get required(): boolean {
|
get required(): boolean {
|
||||||
return this.requiredValue;
|
return this.requiredValue;
|
||||||
@ -191,9 +192,8 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI
|
|||||||
|
|
||||||
fetchRuleChain(searchText?: string): Observable<Array<BaseData<EntityId>>> {
|
fetchRuleChain(searchText?: string): Observable<Array<BaseData<EntityId>>> {
|
||||||
this.searchText = searchText;
|
this.searchText = searchText;
|
||||||
// @voba: at the moment device profiles are not supported by edge, so 'core' hardcoded
|
|
||||||
return this.entityService.getEntitiesByNameFilter(EntityType.RULE_CHAIN, searchText,
|
return this.entityService.getEntitiesByNameFilter(EntityType.RULE_CHAIN, searchText,
|
||||||
50, RuleChainType.CORE, {ignoreLoading: true}).pipe(
|
50, this.ruleChainType, {ignoreLoading: true}).pipe(
|
||||||
catchError(() => of([]))
|
catchError(() => of([]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export interface AssetProfile extends BaseData<AssetProfileId>, ExportableEntity
|
|||||||
defaultRuleChainId?: RuleChainId;
|
defaultRuleChainId?: RuleChainId;
|
||||||
defaultDashboardId?: DashboardId;
|
defaultDashboardId?: DashboardId;
|
||||||
defaultQueueName?: string;
|
defaultQueueName?: string;
|
||||||
|
defaultEdgeRuleChainId?: RuleChainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssetProfileInfo extends EntityInfoData {
|
export interface AssetProfileInfo extends EntityInfoData {
|
||||||
|
|||||||
@ -579,6 +579,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId>, ExportableEnti
|
|||||||
firmwareId?: OtaPackageId;
|
firmwareId?: OtaPackageId;
|
||||||
softwareId?: OtaPackageId;
|
softwareId?: OtaPackageId;
|
||||||
profileData: DeviceProfileData;
|
profileData: DeviceProfileData;
|
||||||
|
defaultEdgeRuleChainId?: RuleChainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceProfileInfo extends EntityInfoData {
|
export interface DeviceProfileInfo extends EntityInfoData {
|
||||||
|
|||||||
@ -1280,6 +1280,8 @@
|
|||||||
"description": "Description",
|
"description": "Description",
|
||||||
"default": "Default",
|
"default": "Default",
|
||||||
"default-rule-chain": "Default rule chain",
|
"default-rule-chain": "Default rule chain",
|
||||||
|
"default-edge-rule-chain": "Default edge rule chain",
|
||||||
|
"default-edge-rule-chain-hint": "Used on edge as rule chain to process incoming data for assets of this asset profile",
|
||||||
"mobile-dashboard": "Mobile dashboard",
|
"mobile-dashboard": "Mobile dashboard",
|
||||||
"mobile-dashboard-hint": "Used by mobile application as a asset details dashboard",
|
"mobile-dashboard-hint": "Used by mobile application as a asset details dashboard",
|
||||||
"select-queue-hint": "Select from a drop-down list.",
|
"select-queue-hint": "Select from a drop-down list.",
|
||||||
@ -1340,6 +1342,8 @@
|
|||||||
"profile-configuration": "Profile configuration",
|
"profile-configuration": "Profile configuration",
|
||||||
"transport-configuration": "Transport configuration",
|
"transport-configuration": "Transport configuration",
|
||||||
"default-rule-chain": "Default rule chain",
|
"default-rule-chain": "Default rule chain",
|
||||||
|
"default-edge-rule-chain": "Default edge rule chain",
|
||||||
|
"default-edge-rule-chain-hint": "Used on edge as rule chain to process incoming data for devices of this device profile",
|
||||||
"mobile-dashboard": "Mobile dashboard",
|
"mobile-dashboard": "Mobile dashboard",
|
||||||
"mobile-dashboard-hint": "Used by mobile application as a device details dashboard",
|
"mobile-dashboard-hint": "Used by mobile application as a device details dashboard",
|
||||||
"select-queue-hint": "Select from a drop-down list.",
|
"select-queue-hint": "Select from a drop-down list.",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user