Device info view improvements
This commit is contained in:
parent
dcbc4c5c7d
commit
9e589c8044
@ -16,16 +16,27 @@
|
|||||||
|
|
||||||
-- DEVICE INFO VIEW START
|
-- DEVICE INFO VIEW START
|
||||||
|
|
||||||
DROP VIEW IF EXISTS device_info_view CASCADE;
|
DROP VIEW IF EXISTS device_info_active_attribute_view CASCADE;
|
||||||
CREATE OR REPLACE VIEW device_info_view as
|
CREATE OR REPLACE VIEW device_info_active_attribute_view AS
|
||||||
SELECT d.*
|
SELECT d.*
|
||||||
, c.title as customer_title
|
, c.title as customer_title
|
||||||
, c.additional_info::json->>'isPublic' as customer_is_public
|
, COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public
|
||||||
, d.type as device_profile_name
|
, d.type as device_profile_name
|
||||||
, (select bool_v from attribute_kv da where da.entity_id = d.id and da.attribute_key = 'active') as attribute_active
|
, COALESCE(da.bool_v, FALSE) as active
|
||||||
, (select bool_v from ts_kv_latest dt where dt.entity_id = d.id and dt.key = (select key_id from ts_kv_dictionary where key = 'active')) as ts_active
|
|
||||||
FROM device d
|
FROM device d
|
||||||
LEFT JOIN customer c ON c.id = d.customer_id;
|
LEFT JOIN customer c ON c.id = d.customer_id
|
||||||
|
LEFT JOIN attribute_kv da ON da.entity_id = d.id and da.attribute_key = 'active';
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS device_info_active_ts_view CASCADE;
|
||||||
|
CREATE OR REPLACE VIEW device_info_active_ts_view AS
|
||||||
|
SELECT d.*
|
||||||
|
, c.title as customer_title
|
||||||
|
, COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public
|
||||||
|
, d.type as device_profile_name
|
||||||
|
, COALESCE(dt.bool_v, FALSE) as active
|
||||||
|
FROM device d
|
||||||
|
LEFT JOIN customer c ON c.id = d.customer_id
|
||||||
|
LEFT JOIN ts_kv_latest dt ON dt.entity_id = d.id and dt.key = (select key_id from ts_kv_dictionary where key = 'active');
|
||||||
|
|
||||||
-- DEVICE INFO VIEW END
|
-- DEVICE INFO VIEW END
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,9 @@ public class ThingsboardInstallService {
|
|||||||
@Value("${install.load_demo:false}")
|
@Value("${install.load_demo:false}")
|
||||||
private Boolean loadDemo;
|
private Boolean loadDemo;
|
||||||
|
|
||||||
|
@Value("${state.persistToTelemetry:false}")
|
||||||
|
private boolean persistToTelemetry;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EntityDatabaseSchemaService entityDatabaseSchemaService;
|
private EntityDatabaseSchemaService entityDatabaseSchemaService;
|
||||||
|
|
||||||
@ -247,6 +250,7 @@ public class ThingsboardInstallService {
|
|||||||
case "3.4.4":
|
case "3.4.4":
|
||||||
log.info("Upgrading ThingsBoard from version 3.4.4 to 3.5.0 ...");
|
log.info("Upgrading ThingsBoard from version 3.4.4 to 3.5.0 ...");
|
||||||
databaseEntitiesUpgradeService.upgradeDatabase("3.4.4");
|
databaseEntitiesUpgradeService.upgradeDatabase("3.4.4");
|
||||||
|
entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry);
|
||||||
log.info("Updating system data...");
|
log.info("Updating system data...");
|
||||||
systemDataLoaderService.updateSystemWidgets();
|
systemDataLoaderService.updateSystemWidgets();
|
||||||
if (!getEnv("SKIP_DEFAULT_NOTIFICATION_CONFIGS_CREATION", false)) {
|
if (!getEnv("SKIP_DEFAULT_NOTIFICATION_CONFIGS_CREATION", false)) {
|
||||||
@ -272,6 +276,8 @@ public class ThingsboardInstallService {
|
|||||||
|
|
||||||
entityDatabaseSchemaService.createDatabaseSchema();
|
entityDatabaseSchemaService.createDatabaseSchema();
|
||||||
|
|
||||||
|
entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry);
|
||||||
|
|
||||||
log.info("Installing DataBase schema for timeseries...");
|
log.info("Installing DataBase schema for timeseries...");
|
||||||
|
|
||||||
if (noSqlKeyspaceService != null) {
|
if (noSqlKeyspaceService != null) {
|
||||||
|
|||||||
@ -16,4 +16,7 @@
|
|||||||
package org.thingsboard.server.service.install;
|
package org.thingsboard.server.service.install;
|
||||||
|
|
||||||
public interface EntityDatabaseSchemaService extends DatabaseSchemaService {
|
public interface EntityDatabaseSchemaService extends DatabaseSchemaService {
|
||||||
|
|
||||||
|
void createOrUpdateDeviceInfoView(boolean activityStateInTelemetry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,4 +39,10 @@ public class SqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaSer
|
|||||||
executeQueryFromFile(SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL);
|
executeQueryFromFile(SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createOrUpdateDeviceInfoView(boolean activityStateInTelemetry) {
|
||||||
|
String sourceViewName = activityStateInTelemetry ? "device_info_active_ts_view" : "device_info_active_attribute_view";
|
||||||
|
executeQuery("DROP VIEW IF EXISTS device_info_view CASCADE;");
|
||||||
|
executeQuery("CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM " + sourceViewName + ";");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -645,6 +645,10 @@ state:
|
|||||||
# Should be greater then transport.sessions.report_timeout
|
# Should be greater then transport.sessions.report_timeout
|
||||||
defaultInactivityTimeoutInSec: "${DEFAULT_INACTIVITY_TIMEOUT:600}"
|
defaultInactivityTimeoutInSec: "${DEFAULT_INACTIVITY_TIMEOUT:600}"
|
||||||
defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:60}"
|
defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:60}"
|
||||||
|
# Controls whether we store device 'active' flag in attributes (default) or telemetry.
|
||||||
|
# If you device to change this parameter, you should re-create the device info view as one of the following:
|
||||||
|
# If 'persistToTelemetry' is changed from 'false' to 'true': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_ts_view;'
|
||||||
|
# If 'persistToTelemetry' is changed from 'true' to 'false': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view;'
|
||||||
persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}"
|
persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}"
|
||||||
|
|
||||||
tbel:
|
tbel:
|
||||||
|
|||||||
@ -46,12 +46,6 @@ public abstract class DaoUtil {
|
|||||||
return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> PageData<T> toPageData(Page<? extends ToData<T>> page, Object... params) {
|
|
||||||
List<T> data = convertDataList(page.getContent(), params);
|
|
||||||
return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> PageData<T> pageToPageData(Page<T> page) {
|
public static <T> PageData<T> pageToPageData(Page<T> page) {
|
||||||
return new PageData<>(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
return new PageData<>(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
||||||
}
|
}
|
||||||
@ -85,19 +79,6 @@ public abstract class DaoUtil {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> convertDataList(Collection<? extends ToData<T>> toDataList, Object... params) {
|
|
||||||
List<T> list = Collections.emptyList();
|
|
||||||
if (toDataList != null && !toDataList.isEmpty()) {
|
|
||||||
list = new ArrayList<>();
|
|
||||||
for (ToData<T> object : toDataList) {
|
|
||||||
if (object != null) {
|
|
||||||
list.add(object.toData(params));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T getData(ToData<T> data) {
|
public static <T> T getData(ToData<T> data) {
|
||||||
T object = null;
|
T object = null;
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@ -106,15 +87,6 @@ public abstract class DaoUtil {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T getData(ToData<T> data, Object... params) {
|
|
||||||
T object = null;
|
|
||||||
if (data != null) {
|
|
||||||
object = data.toData(params);
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> T getData(Optional<? extends ToData<T>> data) {
|
public static <T> T getData(Optional<? extends ToData<T>> data) {
|
||||||
T object = null;
|
T object = null;
|
||||||
if (data.isPresent()) {
|
if (data.isPresent()) {
|
||||||
|
|||||||
@ -172,8 +172,7 @@ public class ModelConstants {
|
|||||||
public static final String DEVICE_CUSTOMER_TITLE_PROPERTY = "customer_title";
|
public static final String DEVICE_CUSTOMER_TITLE_PROPERTY = "customer_title";
|
||||||
public static final String DEVICE_CUSTOMER_IS_PUBLIC_PROPERTY = "customer_is_public";
|
public static final String DEVICE_CUSTOMER_IS_PUBLIC_PROPERTY = "customer_is_public";
|
||||||
public static final String DEVICE_DEVICE_PROFILE_NAME_PROPERTY = "device_profile_name";
|
public static final String DEVICE_DEVICE_PROFILE_NAME_PROPERTY = "device_profile_name";
|
||||||
public static final String DEVICE_ATTR_ACTIVE_PROPERTY = "attribute_active";
|
public static final String DEVICE_ACTIVE_PROPERTY = "active";
|
||||||
public static final String DEVICE_TS_ACTIVE_PROPERTY = "ts_active";
|
|
||||||
|
|
||||||
public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text";
|
public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text";
|
||||||
public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text";
|
public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text";
|
||||||
|
|||||||
@ -29,7 +29,4 @@ public interface ToData<T> {
|
|||||||
*/
|
*/
|
||||||
T toData();
|
T toData();
|
||||||
|
|
||||||
default T toData(Object... params) {
|
|
||||||
return toData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,8 +24,6 @@ import org.thingsboard.server.dao.model.ModelConstants;
|
|||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ -34,23 +32,14 @@ import java.util.Map;
|
|||||||
@Table(name = ModelConstants.DEVICE_INFO_VIEW_COLUMN_FAMILY_NAME)
|
@Table(name = ModelConstants.DEVICE_INFO_VIEW_COLUMN_FAMILY_NAME)
|
||||||
public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
|
public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
|
||||||
|
|
||||||
public static final Map<String, String> attrActiveColumnMap = new HashMap<>();
|
|
||||||
public static final Map<String, String> tsActiveColumnMap = new HashMap<>();
|
|
||||||
static {
|
|
||||||
attrActiveColumnMap.put("active", "attributeActive");
|
|
||||||
tsActiveColumnMap.put("active", "tsActive");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Column(name = ModelConstants.DEVICE_CUSTOMER_TITLE_PROPERTY)
|
@Column(name = ModelConstants.DEVICE_CUSTOMER_TITLE_PROPERTY)
|
||||||
private String customerTitle;
|
private String customerTitle;
|
||||||
@Column(name = ModelConstants.DEVICE_CUSTOMER_IS_PUBLIC_PROPERTY)
|
@Column(name = ModelConstants.DEVICE_CUSTOMER_IS_PUBLIC_PROPERTY)
|
||||||
private Boolean customerIsPublic;
|
private boolean customerIsPublic;
|
||||||
@Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_NAME_PROPERTY)
|
@Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_NAME_PROPERTY)
|
||||||
private String deviceProfileName;
|
private String deviceProfileName;
|
||||||
@Column(name = ModelConstants.DEVICE_ATTR_ACTIVE_PROPERTY)
|
@Column(name = ModelConstants.DEVICE_ACTIVE_PROPERTY)
|
||||||
private Boolean attributeActive;
|
private boolean active;
|
||||||
@Column(name = ModelConstants.DEVICE_TS_ACTIVE_PROPERTY)
|
|
||||||
private Boolean tsActive;
|
|
||||||
|
|
||||||
public DeviceInfoEntity() {
|
public DeviceInfoEntity() {
|
||||||
super();
|
super();
|
||||||
@ -59,13 +48,7 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceInfo toData() {
|
public DeviceInfo toData() {
|
||||||
return toData(false);
|
return new DeviceInfo(super.toDevice(), customerTitle, customerIsPublic, deviceProfileName, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeviceInfo toData(Object... persistToTelemetry) {
|
|
||||||
boolean attr = persistToTelemetry.length == 0 || !(Boolean) persistToTelemetry[0];
|
|
||||||
return new DeviceInfo(super.toDevice(), customerTitle, Boolean.TRUE.equals(customerIsPublic), deviceProfileName,
|
|
||||||
attr ? Boolean.TRUE.equals(attributeActive) : Boolean.TRUE.equals(tsActive));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,10 +21,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||||
import org.thingsboard.server.common.data.DeviceIdInfo;
|
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
|
||||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
|
||||||
import org.thingsboard.server.dao.ExportableEntityRepository;
|
import org.thingsboard.server.dao.ExportableEntityRepository;
|
||||||
import org.thingsboard.server.dao.model.sql.DeviceEntity;
|
import org.thingsboard.server.dao.model.sql.DeviceEntity;
|
||||||
import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
|
import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
|
||||||
@ -125,7 +121,7 @@ public interface DeviceRepository extends JpaRepository<DeviceEntity, UUID>, Exp
|
|||||||
"AND (:customerId IS NULL OR d.customerId = uuid(:customerId)) " +
|
"AND (:customerId IS NULL OR d.customerId = uuid(:customerId)) " +
|
||||||
"AND ((:deviceType) IS NULL OR d.type = :deviceType) " +
|
"AND ((:deviceType) IS NULL OR d.type = :deviceType) " +
|
||||||
"AND (:deviceProfileId IS NULL OR d.deviceProfileId = uuid(:deviceProfileId)) " +
|
"AND (:deviceProfileId IS NULL OR d.deviceProfileId = uuid(:deviceProfileId)) " +
|
||||||
"AND ((:filterByActive) IS FALSE OR (((:persistToTelemetry) IS TRUE AND d.tsActive = :deviceActive) OR ((:persistToTelemetry) IS FALSE AND d.attributeActive = :deviceActive))) " +
|
"AND ((:filterByActive) IS FALSE OR d.active = :deviceActive) " +
|
||||||
"AND (LOWER(d.searchText) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
"AND (LOWER(d.searchText) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
||||||
"OR LOWER(d.label) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
"OR LOWER(d.label) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
||||||
"OR LOWER(d.type) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
"OR LOWER(d.type) LIKE LOWER(CONCAT('%', :textSearch, '%')) " +
|
||||||
@ -135,7 +131,6 @@ public interface DeviceRepository extends JpaRepository<DeviceEntity, UUID>, Exp
|
|||||||
@Param("deviceType") String type,
|
@Param("deviceType") String type,
|
||||||
@Param("deviceProfileId") String deviceProfileId,
|
@Param("deviceProfileId") String deviceProfileId,
|
||||||
@Param("filterByActive") boolean filterByActive,
|
@Param("filterByActive") boolean filterByActive,
|
||||||
@Param("persistToTelemetry") boolean persistToTelemetry,
|
|
||||||
@Param("deviceActive") boolean active,
|
@Param("deviceActive") boolean active,
|
||||||
@Param("textSearch") String textSearch,
|
@Param("textSearch") String textSearch,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
@ -178,7 +173,7 @@ public interface DeviceRepository extends JpaRepository<DeviceEntity, UUID>, Exp
|
|||||||
/**
|
/**
|
||||||
* Count devices by tenantId.
|
* Count devices by tenantId.
|
||||||
* Custom query applied because default QueryDSL produces slow count(id).
|
* Custom query applied because default QueryDSL produces slow count(id).
|
||||||
* <p>
|
*
|
||||||
* There is two way to count devices.
|
* There is two way to count devices.
|
||||||
* OPTIMAL: count(*)
|
* OPTIMAL: count(*)
|
||||||
* - returns _row_count_ and use index-only scan (super fast).
|
* - returns _row_count_ and use index-only scan (super fast).
|
||||||
|
|||||||
@ -64,11 +64,6 @@ import java.util.UUID;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
|
public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
|
||||||
|
|
||||||
@Value("${state.persistToTelemetry:false}")
|
|
||||||
private boolean persistToTelemetry;
|
|
||||||
|
|
||||||
private Map<String, String> activeColumnMap;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceRepository deviceRepository;
|
private DeviceRepository deviceRepository;
|
||||||
|
|
||||||
@ -85,14 +80,9 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
|
|||||||
return deviceRepository;
|
return deviceRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
activeColumnMap = persistToTelemetry ? DeviceInfoEntity.tsActiveColumnMap : DeviceInfoEntity.attrActiveColumnMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceInfo findDeviceInfoById(TenantId tenantId, UUID deviceId) {
|
public DeviceInfo findDeviceInfoById(TenantId tenantId, UUID deviceId) {
|
||||||
return DaoUtil.getData(deviceRepository.findDeviceInfoById(deviceId), persistToTelemetry);
|
return DaoUtil.getData(deviceRepository.findDeviceInfoById(deviceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -128,10 +118,9 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
|
|||||||
filter.getType(),
|
filter.getType(),
|
||||||
DaoUtil.getStringId(filter.getDeviceProfileId()),
|
DaoUtil.getStringId(filter.getDeviceProfileId()),
|
||||||
filter.getActive() != null,
|
filter.getActive() != null,
|
||||||
persistToTelemetry,
|
|
||||||
Boolean.TRUE.equals(filter.getActive()),
|
Boolean.TRUE.equals(filter.getActive()),
|
||||||
Objects.toString(pageLink.getTextSearch(), ""),
|
Objects.toString(pageLink.getTextSearch(), ""),
|
||||||
DaoUtil.toPageable(pageLink, activeColumnMap)), persistToTelemetry);
|
DaoUtil.toPageable(pageLink)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -859,15 +859,27 @@ CREATE TABLE IF NOT EXISTS user_settings (
|
|||||||
CONSTRAINT user_settings_pkey PRIMARY KEY (user_id, type)
|
CONSTRAINT user_settings_pkey PRIMARY KEY (user_id, type)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW device_info_view as
|
DROP VIEW IF EXISTS device_info_active_attribute_view CASCADE;
|
||||||
|
CREATE OR REPLACE VIEW device_info_active_attribute_view AS
|
||||||
SELECT d.*
|
SELECT d.*
|
||||||
, c.title as customer_title
|
, c.title as customer_title
|
||||||
, c.additional_info::json->>'isPublic' as customer_is_public
|
, COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public
|
||||||
, d.type as device_profile_name
|
, d.type as device_profile_name
|
||||||
, (select bool_v from attribute_kv da where da.entity_id = d.id and da.attribute_key = 'active') as attribute_active
|
, COALESCE(da.bool_v, FALSE) as active
|
||||||
, (select bool_v from ts_kv_latest dt where dt.entity_id = d.id and dt.key = (select key_id from ts_kv_dictionary where key = 'active')) as ts_active
|
|
||||||
FROM device d
|
FROM device d
|
||||||
LEFT JOIN customer c ON c.id = d.customer_id;
|
LEFT JOIN customer c ON c.id = d.customer_id
|
||||||
|
LEFT JOIN attribute_kv da ON da.entity_id = d.id and da.attribute_key = 'active';
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS device_info_active_ts_view CASCADE;
|
||||||
|
CREATE OR REPLACE VIEW device_info_active_ts_view AS
|
||||||
|
SELECT d.*
|
||||||
|
, c.title as customer_title
|
||||||
|
, COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public
|
||||||
|
, d.type as device_profile_name
|
||||||
|
, COALESCE(dt.bool_v, FALSE) as active
|
||||||
|
FROM device d
|
||||||
|
LEFT JOIN customer c ON c.id = d.customer_id
|
||||||
|
LEFT JOIN ts_kv_latest dt ON dt.entity_id = d.id and dt.key = (select key_id from ts_kv_dictionary where key = 'active');
|
||||||
|
|
||||||
DROP VIEW IF EXISTS alarm_info CASCADE;
|
DROP VIEW IF EXISTS alarm_info CASCADE;
|
||||||
CREATE VIEW alarm_info AS
|
CREATE VIEW alarm_info AS
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user