1. 概述
本文主要研究 thingsboard 各種實體在關系型數據庫 postgres 中的存儲。
2. 安裝與配置使用 Postgresql 數據庫
從源碼編譯安裝參考 : https://thingsboard.io/docs/user-guide/contribution/how-to-contribute/
編譯運行后,需創建 thingsboard 數據庫:
psql -U postgres -d postgres -h 127.0.0.1 -W
CREATE DATABASE thingsboard;
\q
Postgresql 的基本使用,見 http://www.atjiang.com/postgresql-beginner-11-tasks/
Thingsboard v2.4 中,默認使用的數據庫用戶名和密碼都是 postgres, 見 /application/src/main/resources/thingsboard.yml:
datasource:
driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}"
url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}"
username: "${SPRING_DATASOURCE_USERNAME:postgres}"
password: "${SPRING_DATASOURCE_PASSWORD:postgres}"
創建 schema 並導入測試數據:
cd ~/workspace/thingsboard/application/target/bin/install
chmod +x install_dev_db.sh
./install_dev_db.sh
登錄測試
用戶名 tenant@thingsboard.org
密碼 tenant
實體
Tenants 租戶
是一個獨立的商業實體:比如個人或組織,可以擁有若產生多個設備或資產。一個租戶可有多個租戶管理員用戶及多個客戶。
可將它理解為代理商,中間商,如中國移動是一個 tenant, 承包了某地區的所有項目,信息保存在 tenant 表中。
Customers 客戶
也是一個獨立的商業實體:如何個人或組織,客戶從租戶那購買設備和資產。一個客戶中可有多個用戶。
可將它理解為甲方客戶,如某單位或企業,從租戶中國移動那購買服務。
信息保存在 customer 表中, 通過 tenant_id 關聯相應的 tenant。
Users 用戶
用戶登錄系統,查看信息並管理實體的賬號。系統中創建的用戶,保存於 tb_user 中。
通過 customer_id 和 tenant_id 關聯相應的租戶和客戶,用戶權限由 authority 字段指定,值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/security/Authority.java
public enum Authority {
SYS_ADMIN(0),
TENANT_ADMIN(1),
CUSTOMER_USER(2),
REFRESH_TOKEN(10);
}
customer_id 和 tenant_id 有一個默認的值 1b21dd2138140008080808080808080,該值應該為系統中的一個默認 Tenant 和 Customer 值。
例如系統管理員賬戶 "sysadmin@thingsboard.org" 對應的 customer_id 和 tenant_id 即為該值。
Devices 設備
設備可上傳遙測數據或執行 RPC 命令。
保存於 device 表中,通過 customer_id 和 tenant_id 關聯相應的租戶和客戶。設備類型由 type 字符串字段指定,默認為 default, 可自由創建新值。
新建的設備,其默認 customer_id 為 1b21dd2138140008080808080808080,該值應該為系統中的一個默認 Customer 值。
通過設備管理界面可以分配給指定客戶。
設備的訪問憑證信息保存在表 device_credentials 中,類型由 credentials_type 字段指定,類型值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentialsType.java
public enum DeviceCredentialsType {
ACCESS_TOKEN,
X509_CERTIFICATE
}
Assets 資產
一種用於關聯其它設備和資產的抽象實體,如區域、建築物、單位等,是一個容器概念。 保存於表 asset 中。
Alarms 警報
與各種實體關聯的警報事件。
保存於表 alarm,由 originator_id 和 originator_type 關聯實體,狀態由 status 字段指定,值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmSearchStatus.java
public enum AlarmSearchStatus {
ANY, ACTIVE, CLEARED, ACK, UNACK
}
Dashboards
可視化面板,可可視化數據,並操控設備。
保存於表 dashboard 中,Dashboard 由 tenant 所有,通過 tenant_id 字段關聯。並可以分配給多人 customer, 分配信息保存在 assigned_customers 字段中,如:
[
{
"customerId":{
"entityType":"CUSTOMER",
"id":"5c3c4ff0-8763-11ea-b734-6151c7bf4d3f"
},
"title":"Customer B",
"public":false
},
{
"customerId":{
"entityType":"CUSTOMER",
"id":"5c360e60-8763-11ea-b734-6151c7bf4d3f"
},
"title":"Customer A",
"public":false
}
]
Rule Node 規則結點
處理結點,對上報的信息及實體事件進行處理。
保存在表 rule_node 中,通過 rule_chain_id 關聯到某個規則鏈。
系統已創建了多種結點類型,當前結點類型在 type 字段中指定,值例如(有很多):
- "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode"
- "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode"
- "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode"
- "org.thingsboard.rule.engine.action.TbLogNode"
- "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode"
見 thingsboard/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java, thingsboard/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java 等文件中的定義。
配置信息保存在字段 configuration 中,是 JSON 字串,如 {"timeoutInSeconds":60}。
additional_info 字段中保存當前結點在規則鏈配置界面中的坐標,是 JSON 字串,如 {"layoutX":824,"layoutY":138}。
Rule Chain 規則鏈
關聯的多個規則結點的一個邏輯單元。
保存於表 rule_chain 中,首個結點通過 first_rule_node_id 指定,通過 root boolean 指定是否為根鏈,通過 tenant_id 關聯 Tenant。描述信息等以 JSON 字串形式保存在 additional_info 字段中。
所有實體支持屬性、遙測數據和關聯: Attributes, Telemetry date, Relations.
Attributes 屬性
屬性值是鍵值對, 保存於表 attribute_kv 中。實體由 entity_type 和 entity_id 字段關聯,屬性類型由 attribute_type 指定,值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
public class DataConstants {
public static final String CLIENT_SCOPE = "CLIENT_SCOPE";
public static final String SERVER_SCOPE = "SERVER_SCOPE";
public static final String SHARED_SCOPE = "SHARED_SCOPE";
public static final String[] allScopes() {
return new String[]{CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE};
}
kv 值中的 key 在 attribute_key 中保存,value 在 bool_v, str_v, long_v, dbl_v 字段其中一個中保存,分別表示為 bool, string, long, double 值。
Telemetry data 遙測數據
時序數據。
歷史值在 ts_kv 表中保存, 最新數據在 ts_kv_latest 表中保存。
實體由 entity_type 和 entity_id 字段關聯,key 在 key 字段,時間在 ts 字段,值在 bool_v, str_v, long_v, dbl_v。
Relations 關聯
實體間的有向連接關系信息。
保存於表 relation 中,關聯是兩個實體間的一種關系,由 from_id, from_type 字段指定 from 端的實體,實體類型值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
public enum EntityType {
TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE
}
由 to_id, to_type 字段指定 to 端的實體。
關聯關系由 relation_type_group 和 relation_type 字段指定。
Audit Logs 審計日志
審計/操作記錄信息保存在表 audit_log 中,操作者通過 tenant_id, customer_id, user_id, user_name 字段指定,操作對象通過 entity_id, entity_type, entity_name 字段指定, 操作類型由 action_type 字段指定,值見:
// thingsboard/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
public enum ActionType {
ADDED(false), // log entity
DELETED(false), // log string id
UPDATED(false), // log entity
ATTRIBUTES_UPDATED(false), // log attributes/values
ATTRIBUTES_DELETED(false), // log attributes
TIMESERIES_DELETED(false), // log timeseries
RPC_CALL(false), // log method and params
CREDENTIALS_UPDATED(false), // log new credentials
ASSIGNED_TO_CUSTOMER(false), // log customer name
UNASSIGNED_FROM_CUSTOMER(false), // log customer name
ACTIVATED(false), // log string id
SUSPENDED(false), // log string id
CREDENTIALS_READ(true), // log device id
ATTRIBUTES_READ(true), // log attributes
RELATION_ADD_OR_UPDATE(false),
RELATION_DELETED(false),
RELATIONS_DELETED(false),
ALARM_ACK(false),
ALARM_CLEAR(false),
LOGIN(false),
LOGOUT(false),
LOCKOUT(false);
private final boolean isRead;
ActionType(boolean isRead) {
this.isRead = isRead;
}
}
操作數據以 JSON 字串形式保存在 action_data 中。
操作狀態在 action_status 字段指定,值有 SUCCESS 和 FAILURE,如果失敗,則失敗信息在 action_failure_details 字段中保存,如 PRC Error: Timeout。
