feat(processor): 添加循环名称自动生成的配置开关
新增环境变量 ENABLE_LOOP_NAME_AUTO_GENERATION 用于控制当缓存未命中时是否自动生成循环名称。当设置为 false 时,系统将不再生成 [类型-地址-回路] 格式的备用名称,而是直接返回 null。更新了配置文件、处理器逻辑并添加了相应的单元测试。
This commit is contained in:
@@ -34,3 +34,5 @@ REDIS_DB=15
|
||||
REDIS_CONNECT_TIMEOUT_MS=5000
|
||||
|
||||
ACTION_TYPE_DEV_TYPE_RULES='[{"dev_type":0,"name":"无效设备(也可以被认为是场景)","action_type":"无效"},{"dev_type":1,"name":"强电继电器(输出状态)","action_type":"设备回路状态"},{"dev_type":2,"name":"弱电输入(输入状态)","action_type":"用户操作"},{"dev_type":3,"name":"弱电输出(输出状态)","action_type":"设备回路状态"},{"dev_type":4,"name":"服务信息","action_type":"设备回路状态"},{"dev_type":5,"name":"干节点窗帘","action_type":"设备回路状态"},{"dev_type":6,"name":"开关","action_type":"用户操作"},{"dev_type":7,"name":"空调","action_type":"用户操作"},{"dev_type":8,"name":"红外感应","action_type":"用户操作"},{"dev_type":9,"name":"空气质量检测设备","action_type":"设备回路状态"},{"dev_type":10,"name":"插卡取电","action_type":"用户操作"},{"dev_type":11,"name":"地暖","action_type":"用户操作"},{"dev_type":12,"name":"RCU 设备网络 - 没使用","action_type":""},{"dev_type":13,"name":"窗帘","action_type":"设备回路状态"},{"dev_type":14,"name":"继电器","action_type":"设备回路状态"},{"dev_type":15,"name":"红外发送","action_type":"设备回路状态"},{"dev_type":16,"name":"调光驱动","action_type":"设备回路状态"},{"dev_type":17,"name":"可控硅调光(可控硅状态)","action_type":"设备回路状态"},{"dev_type":18,"name":"灯带(灯带状态) --2025-11-24 取消","action_type":"无效"},{"dev_type":19,"name":"中控","action_type":"无效"},{"dev_type":20,"name":"微信锁 (福 瑞狗的蓝牙锁 默认 0 地址)","action_type":"无效"},{"dev_type":21,"name":"背景音乐(背景音乐状态)","action_type":"设备回路状态"},{"dev_type":22,"name":"房态下发","action_type":"无效"},{"dev_type":23,"name":"主机本地 调光","action_type":"无效"},{"dev_type":24,"name":"485PWM 调光( PWM 调光状态)","action_type":"无效"},{"dev_type":25,"name":"总线调光( PBLED 调光状态) - 没使用 -","action_type":"无效"},{"dev_type":26,"name":"RCU 电源","action_type":"无效"},{"dev_type":27,"name":"A9IO 开关","action_type":"用户操作"},{"dev_type":28,"name":"A9IO 扩展","action_type":"设备回路状态"},{"dev_type":29,"name":"A9IO 电源","action_type":"设备回路状态"},{"dev_type":30,"name":"无线网关轮询(用于轮询控制轮询设备;给无线网关下发配置和询问网关状态)","action_type":"无效"},{"dev_type":31,"name":"无线网关主动(用于主动控制主动设备)","action_type":"无效"},{"dev_type":32,"name":"无线门磁","action_type":"用户操作"},{"dev_type":33,"name":"空气参数显示设备","action_type":"设备回路状态"},{"dev_type":34,"name":"无线继电器红外","action_type":"设备回路状态"},{"dev_type":35,"name":"时间同步","action_type":"设备回路状态"},{"dev_type":36,"name":"监控控制","action_type":"无效"},{"dev_type":37,"name":"旋钮开关控制","action_type":"用户操作"},{"dev_type":38,"name":"CSIO - 类型","action_type":"设备回路状态"},{"dev_type":39,"name":"插卡状态虚拟设备","action_type":"设备回路状态"},{"dev_type":40,"name":"485 新风设备","action_type":"用户操作"},{"dev_type":41,"name":"485 人脸机","action_type":"用户操作"},{"dev_type":42,"name":"中控","action_type":"无效"},{"dev_type":43,"name":"域控","action_type":"无效"},{"dev_type":44,"name":"LCD","action_type":"设备回路状态"},{"dev_type":45,"name":"无卡断电 --2025-11-24 取消","action_type":"无效"},{"dev_type":46,"name":"无卡取电 2","action_type":"用户操作"},{"dev_type":47,"name":"虚拟时间设备","action_type":"设备回路状态"},{"dev_type":48,"name":"PLC 总控","action_type":"设备回路状态"},{"dev_type":49,"name":"PLC 设备 - 恒流调光设备","action_type":"设备回路状态"},{"dev_type":50,"name":"PLC 设备 - 恒压调光设备","action_type":"设备回路状态"},{"dev_type":51,"name":"PLC 设备 - 继电器设备","action_type":"设备回路状态"},{"dev_type":52,"name":"色温调节功能","action_type":"设备回路状态"},{"dev_type":53,"name":"蓝牙音频","action_type":"设备回路状态"},{"dev_type":54,"name":"碳达人","action_type":"用户操作"},{"dev_type":55,"name":"场景还原","action_type":"用户操作"},{"dev_type":56,"name":"全局设置","action_type":"设备回路状态"},{"dev_type":57,"name":"能耗检测","action_type":"设备回路状态"},{"dev_type":241,"name":"CSIO - 类型","action_type":"设备回路状态"}]'
|
||||
|
||||
ENABLE_LOOP_NAME_AUTO_GENERATION=false
|
||||
|
||||
@@ -27,3 +27,5 @@ REDIS_PASSWORD=
|
||||
REDIS_DB=0
|
||||
REDIS_PROJECT_NAME=my-project
|
||||
REDIS_API_BASE_URL=http://localhost:3000
|
||||
|
||||
ENABLE_LOOP_NAME_AUTO_GENERATION=true
|
||||
|
||||
@@ -52,5 +52,6 @@ export const config = {
|
||||
db: parseNumber(process.env.REDIS_DB, 0),
|
||||
projectName: process.env.REDIS_PROJECT_NAME || 'bls-rcu-action',
|
||||
apiBaseUrl: process.env.REDIS_API_BASE_URL || `http://localhost:${parseNumber(process.env.PORT, 3000)}`
|
||||
}
|
||||
},
|
||||
enableLoopNameAutoGeneration: process.env.ENABLE_LOOP_NAME_AUTO_GENERATION === 'true'
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createGuid } from '../utils/uuid.js';
|
||||
import { kafkaPayloadSchema } from '../schema/kafkaPayload.js';
|
||||
import projectMetadata from '../cache/projectMetadata.js';
|
||||
import { config } from '../config/config.js';
|
||||
|
||||
const normalizeDirection = (value) => {
|
||||
if (!value) return null;
|
||||
@@ -241,7 +242,12 @@ export const buildRowsFromPayload = (rawPayload) => {
|
||||
const cachedName = projectMetadata.getLoopName(deviceId, devType, devAddr, devLoop);
|
||||
if (cachedName) return cachedName;
|
||||
|
||||
// 2. Fallback: [TypeName-Addr-Loop]
|
||||
// 2. Check config for auto-generation
|
||||
if (!config.enableLoopNameAutoGeneration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 3. Fallback: [TypeName-Addr-Loop]
|
||||
const typeName = getDevTypeName(devType);
|
||||
if (!typeName) return null; // Should have a name if devType is valid
|
||||
|
||||
|
||||
47
bls-rcu-action-backend/tests/feature_flag_loop_name.test.js
Normal file
47
bls-rcu-action-backend/tests/feature_flag_loop_name.test.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { buildRowsFromPayload } from '../src/processor/index.js';
|
||||
import { config } from '../src/config/config.js';
|
||||
|
||||
describe('Feature Toggle: Loop Name Auto Generation', () => {
|
||||
const basePayload = {
|
||||
ts_ms: 1700000000000,
|
||||
hotel_id: 1001,
|
||||
room_id: '8001',
|
||||
device_id: 'dev_001',
|
||||
direction: '上报',
|
||||
cmd_word: '0x36',
|
||||
frame_id: 1,
|
||||
udp_raw: '00',
|
||||
sys_lock_status: 0,
|
||||
report_count: 0,
|
||||
fault_count: 0,
|
||||
device_list: [
|
||||
{ dev_type: 1, dev_addr: 10, dev_loop: 1, dev_data: 100 }
|
||||
]
|
||||
};
|
||||
|
||||
let originalConfigValue;
|
||||
|
||||
beforeEach(() => {
|
||||
originalConfigValue = config.enableLoopNameAutoGeneration;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
config.enableLoopNameAutoGeneration = originalConfigValue;
|
||||
});
|
||||
|
||||
it('should generate loop_name when flag is true', () => {
|
||||
config.enableLoopNameAutoGeneration = true;
|
||||
const rows = buildRowsFromPayload(basePayload);
|
||||
// Expect format: [1强电继电器(输出状态)-10-1]
|
||||
// The exact name depends on the map, but it should contain brackets and numbers
|
||||
expect(rows[0].loop_name).toBeDefined();
|
||||
expect(rows[0].loop_name).toMatch(/^\[1.*-10-1\]$/);
|
||||
});
|
||||
|
||||
it('should NOT generate loop_name when flag is false', () => {
|
||||
config.enableLoopNameAutoGeneration = false;
|
||||
const rows = buildRowsFromPayload(basePayload);
|
||||
expect(rows[0].loop_name).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -223,7 +223,7 @@ describe('Processor Logic', () => {
|
||||
|
||||
const rows = buildRowsFromPayload(payload);
|
||||
expect(rows[0].loop_name).toBe('Main Chandelier');
|
||||
// dev_type 1 is 'Dev_Host_HVout'
|
||||
expect(rows[1].loop_name).toBe('[1Dev_Host_HVout-10-2]');
|
||||
// dev_type 1 is '强电继电器(输出状态)'
|
||||
expect(rows[1].loop_name).toBe('[1强电继电器(输出状态)-10-2]');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Feature: Loop Name Enrichment
|
||||
|
||||
**Status**: Proposed
|
||||
**Status**: Implemented
|
||||
**Date**: 2026-02-02
|
||||
|
||||
## Summary
|
||||
@@ -0,0 +1,22 @@
|
||||
# Feature: Feature Toggle Loop Name Generation
|
||||
|
||||
**Status**: Implemented
|
||||
**Date**: 2026-02-03
|
||||
|
||||
## Summary
|
||||
Add a configuration switch to control the fallback behavior for `loop_name` generation. Currently, when cache lookup fails, the system auto-generates a name using the format `[Type-Addr-Loop]`. This change allows users to enable or disable this fallback behavior via an environment variable.
|
||||
|
||||
## Requirements
|
||||
1. **Configuration**:
|
||||
- Add `ENABLE_LOOP_NAME_AUTO_GENERATION` to environment variables.
|
||||
- Default behavior should match existing logic (enable generation) if not specified, but user requested explicit control.
|
||||
- If `true`: Perform concatenation `[dev_type名称+'-'+dev_addr+'-'+dev_loop]`.
|
||||
- If `false`: Do not generate name, leave `loop_name` as null (or whatever default is appropriate, likely null).
|
||||
|
||||
2. **Processor Logic**:
|
||||
- In `getLoopNameWithFallback`, check the configuration flag before applying the fallback generation logic.
|
||||
|
||||
## Implementation Plan
|
||||
1. **Config**: Update `src/config/config.js` to parse `ENABLE_LOOP_NAME_AUTO_GENERATION`.
|
||||
2. **Env**: Update `.env` and `.env.example`.
|
||||
3. **Processor**: Update `src/processor/index.js` to respect the flag.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Summary of Changes: Loop Name Features
|
||||
|
||||
**Date**: 2026-02-03
|
||||
**Status**: Archived
|
||||
|
||||
## Overview
|
||||
This archive contains the specifications and proposals for the Loop Name Enrichment and Auto-Generation features. These features enhance the RCU Action Server by enriching event data with descriptive loop names derived from project metadata or fallback generation logic.
|
||||
|
||||
## Included Changes
|
||||
|
||||
### 1. [Feature: Loop Name Enrichment](./feature-loop-name-enrichment.md)
|
||||
- **Goal**: Enrich `rcu_action_events` with `loop_name` by looking up cached metadata from `temporary_project` tables.
|
||||
- **Key Components**:
|
||||
- `ProjectMetadataCache`: Loads rooms and loops data daily.
|
||||
- `loop_name` column added to `rcu_action_events` table.
|
||||
- Processor logic updated to perform lookup.
|
||||
|
||||
### 2. [Feature: Feature Toggle Loop Name Generation](./feature-toggle-loop-name-generation.md)
|
||||
- **Goal**: Provide a configuration switch to control the fallback behavior when cache lookup fails.
|
||||
- **Key Components**:
|
||||
- `ENABLE_LOOP_NAME_AUTO_GENERATION` env var.
|
||||
- Logic to generate `[Type-Addr-Loop]` format only if enabled.
|
||||
- Default behavior is `true` (enabled).
|
||||
|
||||
## Implementation Status
|
||||
- All proposed features have been implemented and verified via unit tests.
|
||||
- Configuration variables are documented in `.env.example`.
|
||||
Reference in New Issue
Block a user