Files
EdgeManager/README.md

306 lines
6.7 KiB
Markdown
Raw Normal View History

2022-07-02 10:59:45 +08:00
# EdgeManagerSCADA系统
2022-07-09 14:30:30 +08:00
- [EdgeManagerSCADA系统](#edgemanagerscada系统)
- [API](#api)
- [class `EDataCapture`](#class-edatacapture)
2022-07-10 03:39:00 +08:00
- [0. HTTP POST: `set_node_data`](#0-http-post-set_node_data)
2022-07-14 11:47:44 +08:00
- [使用指北](#使用指北)
- [后端](#后端)
- [前端](#前端)
2022-07-09 14:30:30 +08:00
- [开发环境](#开发环境)
- [技术细节](#技术细节)
2022-07-10 22:11:08 +08:00
- [0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的](#0-edgemanageredatacaptureedatacapture---set_data为什么是以6710885为大小chunked的)
2022-07-09 14:30:30 +08:00
## API
> API设计最大程度遵循了已有的MES规范。
### class `EDataCapture`
2022-07-10 03:39:00 +08:00
#### 0. HTTP POST: `set_node_data`
2022-07-09 14:30:30 +08:00
**请求**
> 上位机程序中请单次传入尽量多的数据使得性能最大化。
2022-07-10 03:39:00 +08:00
>
> 但仍需兼顾传输速率和超时时间。
>
> 无需指定数值类型,服务端会自动根据已添加的节点信息检查,若不符则会报错。
2022-07-10 03:39:00 +08:00
2022-07-09 14:30:30 +08:00
```json
{
2022-07-10 03:39:00 +08:00
"action": "set_node_data",
"param": {
"working_subclass": <string>,
"data": [
{
"code": <string>,
// value的类型需与type对应
"value": <string | int | float | bool>,
"device_code": [string],
"batch": [string]
},
{
"code": <string>,
"value": <string | int | float | bool>,
"device_code": [string],
"batch": [string]
},
...
]
2022-07-09 14:30:30 +08:00
}
}
```
**返回**
操作成功:
```json
{
"action": "result_set_node_data",
2022-07-10 03:39:00 +08:00
"errcode": 0,
"errmsg": ""
2022-07-09 14:30:30 +08:00
}
```
操作失败(**工序单元尚未登记**
```json
{
"action": "result_set_node_data",
"errcode": 4002,
"errmsg": "未登记过的工序单元!"
}
```
操作失败(**数值类型错误**
```json
{
"action": "result_set_node_data",
"errcode": 4002,
"errmsg": "节点编码和数值类型不匹配!"
}
```
操作失败(不明原因):
2022-07-09 14:30:30 +08:00
```json
{
"action": "result_set_node_data",
2022-07-10 03:39:00 +08:00
"errcode": 4002,
"errmsg": "ROLLBACKed: Bad data received (structure and/or values)"
2022-07-09 14:30:30 +08:00
}
```
2022-07-14 11:47:44 +08:00
## 使用指北
2022-07-10 03:39:00 +08:00
2022-07-14 11:47:44 +08:00
本项目可独立运行也可作为MES的插件使用。
下文简要介绍如何将代码合并入MES中。
2022-07-17 10:50:45 +08:00
需要保证`timescaledb`后显示的版本号在**2.2.0或以上**。
2022-07-16 14:16:16 +08:00
2022-07-14 11:47:44 +08:00
### 后端
2022-07-16 14:16:16 +08:00
添加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
```
2022-07-14 11:47:44 +08:00
目录结构:
```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的代码。
### 前端
2022-07-16 14:16:16 +08:00
添加依赖使用npm
```bash
npm i element-ui @d2-projects/d2-crud -S
npm install -S vue-cheetah-grid
```
添加依赖使用yarn
```bash
yarn add element-ui @d2-projects/d2-crud
yarn add vue-cheetah-grid
```
2022-07-14 11:47:44 +08:00
需要在`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'
Vue.use(ElementUI)
Vue.use(D2Crud)
Vue.use(vueCheetahGrid)
```
此外请参照目录结构中注释进行代码合并:
```pre
📦src
┣ 📂api
┃ ┣ 📂modules
┃ ┃ ┣ 📜scada.configure.api.js # 增添Axios请求
┃ ┃ ┗ 📜sys.user.api.js
┃ ┣ 📜index.js
┃ ┣ 📜service.js
┃ ┗ 📜tools.js
┣ 📂assets
┣ 📂components
┣ 📂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
```
2022-07-10 03:39:00 +08:00
## 开发环境
拉取代码:
```bash
# 建议先配置SSH key pair
2022-07-02 10:59:45 +08:00
git clone ssh://git@118.195.187.246:10022/ysun/EdgeManager.git
cd EdgeManager
```
一键部署PHP workerman和TimescaleDB环境
```bash
docker compose up -d
```
进入交互式Prompt
```bash
2022-07-02 10:59:45 +08:00
docker exec -it edge_manager bash
```
后端调试:
```bash
2022-07-10 03:39:00 +08:00
# In container
php EdgeManager.php --server_name=GPU-server-01 --user=postgres --password=big_dick start
2022-07-09 14:30:30 +08:00
```
2022-07-10 03:39:00 +08:00
前端调试:
```bash
# In host
# yarn
# yarn watch
yarn serve
```
2022-07-09 14:30:30 +08:00
客户端连接:
```bash
# sudo apt install postgresql-client
2022-07-09 14:30:30 +08:00
# 登入
psql -h localhost -U postgres
# 显示数据库列表
\l
```
## 技术细节
2022-07-10 22:11:08 +08:00
### 0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的
2022-07-09 14:30:30 +08:00
2022-07-10 03:39:00 +08:00
首先明确一点根据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');
```
2022-07-09 14:30:30 +08:00
这其中,仅插入部分字段的值,比如:
```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。
2022-07-10 22:11:08 +08:00
而此处我源码中的SQL语句头长度为138 bytes注意末尾空格
2022-07-09 14:30:30 +08:00
![](imgs/sql_head.png)
2022-07-10 22:11:08 +08:00
单个语句体的长度为160 bytes
2022-07-09 14:30:30 +08:00
![](imgs/sql_body.png)
2022-07-10 22:11:08 +08:00
所以其最多可以一次性插入`(1073741823 - 138) / 160`条记录,向下取整后即为`6710885`