feat: 添加回路名称字段并实现元数据缓存查询
在 RCU 事件处理中新增回路名称(loop_name)字段,用于标识具体设备回路。 - 在 rcu_action_events 表中添加 loop_name 字段 - 新增项目元数据缓存模块,每日从 temporary_project 表刷新房间与回路信息 - 处理消息时,根据 device_id、dev_addr 等字段查询缓存获取回路名称 - 若缓存未命中,则根据设备类型规则生成兜底名称 - 更新环境变量、文档及测试用例以适配新功能
This commit is contained in:
113
bls-rcu-action-backend/scripts/generate_rules_from_readme.js
Normal file
113
bls-rcu-action-backend/scripts/generate_rules_from_readme.js
Normal file
@@ -0,0 +1,113 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const readmePath = path.resolve(__dirname, '../../docs/readme.md');
|
||||
const envPath = path.resolve(__dirname, '../.env');
|
||||
const processorPath = path.resolve(__dirname, '../src/processor/index.js');
|
||||
|
||||
try {
|
||||
const readmeContent = fs.readFileSync(readmePath, 'utf8');
|
||||
const lines = readmeContent.split('\n');
|
||||
|
||||
const rules = [];
|
||||
let inTable = false;
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
|
||||
// Detect start of table (approximately)
|
||||
if (trimmed.includes('|dev_type|名称|描述|Action Type|')) {
|
||||
inTable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip separator line
|
||||
if (inTable && trimmed.includes('|---|')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Process table rows
|
||||
if (inTable && trimmed.startsWith('|') && trimmed.endsWith('|')) {
|
||||
const parts = trimmed.split('|').map(p => p.trim());
|
||||
// parts[0] is empty, parts[1] is dev_type, parts[2] is name, parts[3] is description, parts[4] is action_type
|
||||
|
||||
if (parts.length >= 5) {
|
||||
const devTypeStr = parts[1];
|
||||
const description = parts[3];
|
||||
const actionType = parts[4];
|
||||
|
||||
if (!devTypeStr || isNaN(parseInt(devTypeStr))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const devType = parseInt(devTypeStr, 10);
|
||||
|
||||
rules.push({
|
||||
dev_type: devType,
|
||||
name: description, // Use description as name per user request
|
||||
action_type: actionType
|
||||
});
|
||||
}
|
||||
} else if (inTable && trimmed === '') {
|
||||
// Empty line might mean end of table, but let's be loose
|
||||
} else if (inTable && !trimmed.startsWith('|')) {
|
||||
// End of table
|
||||
inTable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by dev_type
|
||||
rules.sort((a, b) => a.dev_type - b.dev_type);
|
||||
|
||||
console.log(`Found ${rules.length} rules.`);
|
||||
|
||||
// 1. Generate JSON for .env
|
||||
const envJson = JSON.stringify(rules);
|
||||
|
||||
// Read existing .env
|
||||
let envContent = fs.readFileSync(envPath, 'utf8');
|
||||
const envKey = 'ACTION_TYPE_DEV_TYPE_RULES';
|
||||
|
||||
// Replace or Append
|
||||
const envLine = `${envKey}='${envJson}'`;
|
||||
const regex = new RegExp(`^${envKey}=.*`, 'm');
|
||||
|
||||
if (regex.test(envContent)) {
|
||||
envContent = envContent.replace(regex, envLine);
|
||||
} else {
|
||||
envContent += `\n${envLine}`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(envPath, envContent, 'utf8');
|
||||
console.log('Updated .env');
|
||||
|
||||
// 2. Generate Object for src/processor/index.js
|
||||
// We need to construct the object string manually to match the code style
|
||||
const mapLines = rules.map(r => {
|
||||
// Escape single quotes in name if present
|
||||
const safeName = r.name.replace(/'/g, "\\'");
|
||||
return ` ${r.dev_type}: { name: '${safeName}', action: '${r.action_type}' }`;
|
||||
});
|
||||
|
||||
const mapString = `const defaultDevTypeActionMap = {\n${mapLines.join(',\n')}\n};`;
|
||||
|
||||
let processorContent = fs.readFileSync(processorPath, 'utf8');
|
||||
|
||||
// Regex to replace the object.
|
||||
const processorRegex = /const defaultDevTypeActionMap = \{[\s\S]*?\};/m;
|
||||
|
||||
if (processorRegex.test(processorContent)) {
|
||||
processorContent = processorContent.replace(processorRegex, mapString);
|
||||
fs.writeFileSync(processorPath, processorContent, 'utf8');
|
||||
console.log('Updated src/processor/index.js');
|
||||
} else {
|
||||
console.error('Could not find defaultDevTypeActionMap in src/processor/index.js');
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
}
|
||||
@@ -27,12 +27,16 @@ CREATE TABLE IF NOT EXISTS rcu_action.rcu_action_events (
|
||||
type_h SMALLINT,
|
||||
details JSONB,
|
||||
extra JSONB,
|
||||
loop_name VARCHAR(255),
|
||||
PRIMARY KEY (ts_ms, guid)
|
||||
) PARTITION BY RANGE (ts_ms);
|
||||
|
||||
ALTER TABLE rcu_action.rcu_action_events
|
||||
ADD COLUMN IF NOT EXISTS device_id VARCHAR(32) NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE rcu_action.rcu_action_events
|
||||
ADD COLUMN IF NOT EXISTS loop_name VARCHAR(255);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_rcu_action_hotel_id ON rcu_action.rcu_action_events (hotel_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcu_action_room_id ON rcu_action.rcu_action_events (room_id);
|
||||
|
||||
Reference in New Issue
Block a user