Files
Web_BLS_RCUAction_Server/docs/readme.md
XuJiacheng 0e6c5c3cc3 feat: 增强Kafka消费者配置并完善action_type分类逻辑
- 支持多实例Kafka消费者,增加并发处理能力
- 新增Kafka配置参数:最大飞行中消息数、获取字节数、等待时间等
- 完善action_type分类逻辑,根据dev_type映射为"用户操作"或"设备回路状态"
- 临时支持hex格式udp_raw自动转换为base64存储
- 增加extra字段支持上游扩展数据传递
- 优化数据库初始化脚本查找路径
- 更新PM2配置,修改应用名称和端口
- 清理开发环境日志文件,将dist目录加入.gitignore
- 更新相关文档说明
2026-01-30 20:09:46 +08:00

156 lines
9.2 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.
# BLS RCU Action Server 开发文档
## 1. 项目概述
本项目旨在构建一个后端服务,负责从 Kafka 接收 RCU客房控制单元的通讯日志解析数据结构并将其持久化存储到 PostgreSQL 数据库中。
核心目标是将不同类型的通讯协议数据0x36 上报、0x0F 下发、ACK统一存储并针对不定长数据结构采用 JSON 格式进行灵活保存。
## 2. 系统架构
**数据流向**: `MCU/Server` (产生数据) -> `Kafka` (消息队列) -> `Action Server` (消费 & 解析) -> `PostgreSQL` (存储)
- **Kafka Topic**: `blwlog4Nodejs-rcu-action-topic` (分区数: 6)
- **数据库**: PostgreSQL
## 3. 数据库设计
数据库名:`bls_rcu_action`
模式名: `rcu_action`
### 3.1 表结构设计
表名: `rcu_action_events`
| 字段名 | 类型 | 说明 | 备注 |
| :--- | :--- | :--- | :--- |
| **guid** | VARCHAR(32) | 主键 (Key2) | 32位无符号UUID |
| **ts_ms** | BIGINT | 日志产生时间 (Key1) | **必填** (L49) |
| **write_ts_ms** | BIGINT | 入库时间 | **必填** (L50) |
| **hotel_id** | INTEGER | 酒店ID | **必填** (L51) Index |
| **room_id** | VARCHAR(32) | 房间ID | **必填** (L52) Index |
| **device_id** | VARCHAR(32) | 设备ID | **必填** (新增) Index |
| **direction** | VARCHAR(10) | 数据方向 | **必填** (L53) "上报"/"下发" Index |
| **cmd_word** | VARCHAR(10) | 命令字 | **必填** (L54) 如 "0x36", "0x0F" Index |
| **frame_id** | INTEGER | 通讯帧号 | **必填** (L55) 用于串联命令与状态 |
| **udp_raw** | TEXT | UDP消息原文 | **必填** (L56) base64字符串当前若上游仍发送十六进制字符串则后端会在入库前临时转换为base64后续会取消该自动转换机制 |
| **action_type** | VARCHAR(20) | 记录行为类型 | **必填** (L57) Index |
| **sys_lock_status** | SMALLINT | 系统锁状态 | (L59) 可空 |
| **report_count** | SMALLINT | 本次上报数量 | (L60) 可空 |
| **dev_type** | SMALLINT | 设备类型 | (L61) 可空 (统一字段) |
| **dev_addr** | SMALLINT | 设备地址 | (L62) 可空 (统一字段) |
| **dev_loop** | INTEGER | 设备回路 | (L63) 可空 (统一字段) |
| **dev_data** | INTEGER | 设备状态 | (L64) 可空 (0x36状态) |
| **fault_count** | SMALLINT | 本次故障数量 | (L65) 可空 |
| **error_type** | SMALLINT | 故障类型 | (L69) 可空 (0x36故障) |
| **error_data** | SMALLINT | 故障内容 | (L70) 可空 (0x36故障) |
| **type_l** | SMALLINT | 执行方式 | 可空 (0x0F下发) |
| **type_h** | SMALLINT | 执行内容 | 可空 (0x0F下发) |
| **details** | JSONB | 业务详情数据 | 存储不定长设备列表、故障信息等 |
| **extra** | JSONB | 扩展信息 | 存储上游传入的extra扩展字段如未提供则为空对象 |
**主键定义**: `(ts_ms, guid)`
**索引定义**: 备注带index的字段为需要索引的字段用于提高查询效率。
### 3.2 字典定义
**Action Type (记录行为类型)**:
- 枚举值ACK和下发控制是0x0F的特殊情况用户操作和设备回路状态是0x36的枚举值
- ACKACK是0x0F的上报独有的所以如果0F且Direction为上报就标记为ACK
- 下发控制0x0F的Direction为下发指令记录为下发控制
- 用户操作0x36上报 的开关、温控器等客户操作设备产生的,属于用户操作
- 设备回路状态0x36上报 的灯光、继电器回路等变化等受控设备,属于设备回路状态
- 用户操作和设备回路状态的具体区分表根据本行数据的dev_type来区分注意这张表是根据dev_type来区分的所以dev_type不能改变否则会导致数据错误另外这个表要写入env配置文件以数组形式保存随时可以更改
|dev_type|名称|描述|Action Type|
|---|---|---|---|
|0|Dev_Host_Invalid|无效设备(也可以被认为是场景)|无效|
|1|Dev_Host_HVout|强电继电器(输出状态)|设备回路状态|
|2|Dev_Host_LVinput|弱电输入(输入状态)|用户操作|
|3|Dev_Host_LVoutput|弱电输出(输出状态)|设备回路状态|
|4|Dev_Host_Service|服务信息|设备回路状态|
|5|Dev_NodeCurtain|干节点窗帘|设备回路状态|
|6|DEV_RS485_SWT|开关|用户操作|
|7|DEV_RS485_TEMP|空调|用户操作|
|8|DEV_RS485_INFRARED|红外感应|用户操作|
|9|DEV_RS485_AirDetect|空气质量检测设备|设备回路状态|
|10|DEV_RS485_CARD|插卡取电|用户操作|
|11|DEV_RS485_HEATER|地暖|用户操作|
|12|Dev_RCU_NET|RCU 设备网络 - 没使用||
|13|DEV_RS485_CURTAIN|窗帘|设备回路状态|
|14|DEV_RS485_RELAY|继电器|设备回路状态|
|15|DEV_RS485_IR_SEND|红外发送|设备回路状态|
|16|DEV_RS485_DIMMING|调光驱动|设备回路状态|
|17|DEV_RS485_TRAIC|可控硅调光(可控硅状态)|设备回路状态|
|18|DEV_RS485_STRIP|灯带(灯带状态) --2025-11-24 取消|无效|
|19|DEV_RS485_CoreCtrl|中控|无效|
|20|DEV_RS485_WxLock|微信锁 (福 瑞狗的蓝牙锁 默认 0 地址)|无效|
|21|DEV_RS485_MUSIC|背景音乐(背景音乐状态)|设备回路状态|
|22|DEV_NET_ROOMSTATE|房态下发|无效|
|23|Dev_Host_PWMLight|主机本地 调光|无效|
|24|DEV_RS485_PWM|485PWM 调光( PWM 调光状态)|无效|
|25|DEV_PB_LED|总线调光( PBLED 调光状态) - 没使用 -|无效|
|26|DEV_RCU_POWER|RCU 电源|无效|
|27|DEV_RS485_A9_IO_SWT|A9IO 开关|用户操作|
|28|DEV_RS485_A9_IO_EXP|A9IO 扩展|设备回路状态|
|29|DEV_RS485_A9_IO_POWER|A9IO 电源|设备回路状态|
|30|DEV_RS485_RFGatewayCycle|无线网关轮询(用于轮询控制轮询设备;给无线网关下发配置和询问网关状态)|无效|
|31|DEV_RS485_RFGatewayHost|无线网关主动(用于主动控制主动设备)|无效|
|32|DEV_RS485_RFGatewayDoor|无线门磁|用户操作|
|33|DEV_RS485_AirReveal|空气参数显示设备|设备回路状态|
|34|DEV_RS485_RFGatewayRelayPir|无线继电器红外|设备回路状态|
|35|Dev_Host_TimeCtrl|时间同步|设备回路状态|
|36|Dev_Rs458_MonitorCtrl|监控控制|无效|
|37|Dev_Rs458_RotaryCtrl|旋钮开关控制|用户操作|
|38|Dev_BUS_C5IO|CSIO - 类型|设备回路状态|
|39|Dev_RS485_CardState|插卡状态虚拟设备|设备回路状态|
|40|DEV_RS485_FreshAir|485 新风设备|用户操作|
|41|DEV_RS485_FaceMach|485 人脸机|用户操作|
|42|DEV_Center_Control|中控|无效|
|43|DEV_Domain_Control|域控|无效|
|44|DEV_RS485_LCD|LCD|设备回路状态|
|45|DEV_Virtual_NoCard|无卡断电 --2025-11-24 取消|无效|
|46|DEV_Virtual_Card|无卡取电 2|用户操作|
|47|DEV_Virtual_Time|虚拟时间设备|设备回路状态|
|48|Dev_Rs485_PB20|PLC 总控|设备回路状态|
|49|Dev_Rs485_PB20_LD|PLC 设备 - 恒流调光设备|设备回路状态|
|50|Dev_Rs485_PB20_LS|PLC 设备 - 恒压调光设备|设备回路状态|
|51|Dev_Rs485_PB20_Relay|PLC 设备 - 继电器设备|设备回路状态|
|52|DEV_Virtual_ColorTemp|色温调节功能|设备回路状态|
|53|Dev_485_BLE_Music|蓝牙音频|设备回路状态|
|54|DEV_Carbon_Saved|碳达人|用户操作|
|55|Dev_Scene_Restore|场景还原|用户操作|
|56|Dev_Virtual_GlobalSet|全局设置|设备回路状态|
|57|Dev_Energy_Monitor|能耗检测|设备回路状态|
|241|Dev_BUS_C5IO|CSIO - 类型|设备回路状态|
**Direction (方向)**:
- `"上报"`: Upload
- `"下发"`: Download
## 4. 数据解析与存储映射
### 4.1 0x36 上报数据 (设备状态/故障)
* **命令字**: "0x36"
* **拆分逻辑**: 根据 `project.md` 说明,一条 UDP 可能包含多个设备状态,需拆分为多条记录入库,每条记录填充 `dev_type` 等字段。同时将完整的不定长列表存入 `details` 以便追溯。
* **Action Type**: 4 (设备回路状态)
**Mapping**:
- `sys_lock_status` -> P0
- `report_count` -> P7
- `dev_type`, `dev_addr`... -> 从 P8~P13 循环解析,每组生成一条 DB 记录
- `details`: `{ "all_devices": [...], "all_faults": [...] }`
- `extra`: `{ "raw_hex": "..." }`
### 4.2 0x0F 下发数据 (控制指令)
* **命令字**: "0x0F"
* **Action Type**: 2 (下发控制)
* **存储逻辑**: 主要是控制指令,通常作为单条记录存储。若包含多个设备控制,可选择存第一条到字段,或仅存入 JSON。根据 "0x0F不定长存为JSON" 的需求,主要依赖 `details` 字段。
**Mapping**:
- `details`: `{ "control_params": [ ... ] }`
- `extra`: `{ "raw_hex": "..." }`
### 4.3 0x0F 上报数据 (ACK)
* **命令字**: "0x0F"
* **Action Type**: "0FACK" (ACK)
**Mapping**:
- `details`: `{ "ack_code": "0x00" }`
- `extra`: `{ "raw_hex": "..." }`