Files
EdgeManager/README.md

361 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# EdgeManagerSCADA系统
- [EdgeManagerSCADA系统](#edgemanagerscada系统)
- [API](#api)
- [class `EDataCapture`](#class-edatacapture)
- [0. HTTP POST: `set_node_data`](#0-http-post-set_node_data)
- [使用指北](#使用指北)
- [后端](#后端)
- [前端](#前端)
- [开发环境](#开发环境)
- [调试环境](#调试环境)
- [技术细节](#技术细节)
- [0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的](#0-edgemanageredatacaptureedatacapture---set_data为什么是以6710885为大小chunked的)
## API
> API设计最大程度遵循了已有的MES规范。
### class `EDataCapture`
#### 0. HTTP POST: `set_node_data`
**请求**
> 上位机程序中请单次传入尽量多的数据使得性能最大化。
>
> 但仍需兼顾传输速率和超时时间。
>
> 无需指定数值类型,服务端会自动根据已添加的节点信息检查,若不符则会报错。
```json
{
"action": "set_node_data",
"param": {
"working_subclass": <string>, // 可选
"data": [
{
"code": <string>,
// value的类型需与type对应
"value": <string | int | float | bool>,
"device_code": [string], // 必需字段
"parent_device_code": [string], // 可选字段对应MES中的code
"batch": [string] // 可选字段
},
{
"code": <string>,
"value": <string | int | float | bool>,
"device_code": [string],
"parent_device_code": [string],
"batch": [string]
},
...
]
}
}
```
**返回**
操作成功:
```json
{
"action": "result_set_node_data",
"errcode": 0,
"errmsg": ""
}
```
操作失败(**工序单元尚未登记**
```json
{
"action": "result_set_node_data",
"errcode": 4002,
"errmsg": "未登记过的工序单元!"
}
```
操作失败(**数值类型错误**
```json
{
"action": "result_set_node_data",
"errcode": 4002,
"errmsg": "节点编码和数值类型不匹配!"
}
```
操作失败(不明原因):
```json
{
"action": "result_set_node_data",
"errcode": 4002,
"errmsg": "ROLLBACKed: Bad data received (structure and/or values)"
}
```
## 使用指北
本项目可独立运行也可作为MES的插件使用。
下文简要介绍如何将代码合并入MES中。
需要保证`timescaledb`的版本在**2.2.0或以上**。
### 后端
添加pg扩展Ubuntu
```bash
sudo apt install php-pgsql
```
添加pg扩展CentOS 7
```bash
sudo yum install php-pgsql
```
添加pg扩展CentOS8
```bash
sudo dnf install php-pgsql
```
目录结构:
```pre
📦EdgeManager
┣ 📂EDataCapture
┃ ┣ 📜EDataCapture.php
┃ ┗ 📜ENodeConfigure.php
┣ 📜Init.php
┗ 📜Utils.php
```
建议使用composer autoload引入。
将目录`EdgeManager`复制至项目后在composer.json内写入
```json
"autoload": {
"psr-4": {
"EdgeManager\\": "EdgeManager/"
},
"files": [
"EdgeManager/Utils.php",
"EdgeManager/Init.php"
]
},
```
运行`composer dump-autoload`即可正常调用EdgeManager的代码。
### 前端
添加依赖(**使用npm**
```bash
npm i element-ui \
@d2-projects/d2-crud \
vue-cheetah-grid \
@d2-projects/vue-table-export \
@d2-projects/vue-table-import \
github-markdown-css \
marked@^2.0.0 \
jschardet -S
```
添加依赖(**使用yarn**
```bash
yarn add element-ui \
@d2-projects/d2-crud \
vue-cheetah-grid \
@d2-projects/vue-table-export \
@d2-projects/vue-table-import \
github-markdown-css \
marked@^2.0.0 \
jschardet
```
需要在`main.js`中增加(全局引入组件):
```js
// D2-Crud
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import D2Crud from '@d2-projects/d2-crud'
// Cheetah-Grid
import vueCheetahGrid from 'vue-cheetah-grid'
// 表格导出插件
import pluginExport from '@d2-projects/vue-table-export'
import pluginImport from '@d2-projects/vue-table-import'
Vue.use(ElementUI)
Vue.use(D2Crud)
Vue.use(vueCheetahGrid)
Vue.use(pluginExport)
Vue.use(pluginImport)
```
*(可选)*`package.json`里更改`element-ui`版本:
```json
"element-ui": ">2.15.9 || 2.15.8",
```
`2.15.9`有一个小[bug](https://github.com/ElemeFE/element/issues/21941),会导致性能下降。
此外请参照目录结构中注释进行代码合并:
```pre
📦src
┣ 📂api
┃ ┣ 📂modules
┃ ┃ ┣ 📜scada.configure.api.js # 增添Axios请求
┃ ┃ ┗ 📜sys.user.api.js
┃ ┣ 📜index.js
┃ ┣ 📜service.js
┃ ┗ 📜tools.js
┣ 📂assets
┣ 📂components
┃ ┣ 📂d2-markdown # 渲染markdown所需组件在D2Admin的基础上精简了功能
┃ ┃ ┗ 📜index.vue
┃ ┗ 📜index.js # 在此处注册d2-markdown
┣ 📂libs
┣ 📂locales
┣ 📂menu
┃ ┗ 📜index.js # 增添菜单
┣ 📂plugin
┣ 📂router
┃ ┣ 📜index.js
┃ ┗ 📜routes.js # 增添路由
┣ 📂store
┣ 📂views
┃ ┣ 📂scada # 增添页面
┃ ┃ ┣ 📂scadaConfigure
┃ ┃ ┃ ┗ 📜index.vue
┃ ┃ ┗ 📂scadaQuery
┃ ┃ ┃ ┗ 📜index.vue
┃ ┗ 📂system
┣ 📜App.vue
┣ 📜i18n.js
┣ 📜main.js
┗ 📜setting.js
```
## 开发环境
拉取代码:
```bash
# 建议先配置SSH key pair
git clone ssh://git@118.195.187.246:10022/ysun/EdgeManager.git
cd EdgeManager
```
一键部署PHP workerman和TimescaleDB环境
```bash
# docker build --network host -t edge_manager .
docker compose up -d
```
进入交互式Prompt
```bash
docker exec -it edge_manager bash
```
后端调试:
```bash
# In container
php EdgeManager.php --no_dup_code --server_name=GPU-server-01 --user=postgres --password=big_dick start
```
前端调试:
```bash
# In host
# yarn
# yarn watch
yarn serve
```
客户端连接:
```bash
# sudo apt install postgresql-client
# 登入
psql -h localhost -U postgres
# 显示数据库列表
\l
```
## 调试环境
不使用`docker compose`创建两个container分别运行EdgeManager和pg
```bash
# cd EdgeManager # 先定位到项目目录方便创建image和挂载
# 创建EdgeManager的image
docker build --network host -t edge_manager .
# 创建container运行EdgeManager
docker run -d --name edge_manager_test -v $PWD:/EdgeManager --network host -it edge_manager
# 创建container运行pg将端口映射到host的55432
docker run -d --name pg_test -v $PWD/config/postgresql.conf:/etc/postgresql/postgresql.conf -p 55432:5432 -e POSTGRES_PASSWORD=big_dick -it timescale/timescaledb-ha:pg14-latest postgres -c 'config_file=/etc/postgresql/postgresql.conf'
# 进入交互式Prompt
docker exec -it edge_manager_test bash
# 启动EdgeManagerworkerman命令省略...
# 常用命令
# 查看全部container
docker ps -a
# 启动已停止的container
docker start [container]
```
## 技术细节
### 0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的
首先明确一点根据PostgreSQL的技术架构条件允许的情况下**一次性插入多条记录是效率最高的**,比如:
```sql
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
```
这其中,仅插入部分字段的值,比如:
```sql
INSERT INTO films (code, title, did, date_prod, kind)
VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
```
的效率又远远不如插入全部列但使用特殊变量DEFAULT替代缺少的字段比如
```sql
INSERT INTO films VALUES
('UA502', 'Bananas', DEFAULT, '1971-07-13', 'Comedy', '82 minutes');
```
PostgreSQL的文档里没有提及这个话题因为源码里为SQL语句的内存分配[指定了一个最大长度常量`MaxAllocSize`](https://github.com/postgres/postgres/blob/2373fe78dfc9d4aa2348a86fffdf8eb9d757e9d5/src/common/stringinfo.c#L28)其大小为比1GB小1字节。这个值可以在编译前手动修改所以理论上每个PG运行的实例都可以不一样如果我们使用的PG并非修改过源码手动编译的那么SQL语句的最大长度为`1024 ** 3 - 1 = 1073741823` bytes。
> 安全起见下述计算假定working_subclass等字段的最大长度均为我们以往约定的45 bytes。
而此处我源码中的SQL语句头长度为138 bytes注意末尾空格
![](imgs/sql_head.png)
单个语句体的长度为160 bytes
![](imgs/sql_body.png)
所以其最多可以一次性插入`(1073741823 - 138) / 160`条记录,向下取整后即为`6710885`