AI_UIAutomation/utils/common/ones-anchor.helper.ts

205 lines
12 KiB
TypeScript

/**
* 设备维度的 ONES 锚点解析:同品类不同型号(UI 相似)用同一脚本,按当前设备动态解析锚点,
* 换 <CAT>_DEVICE 环境变量重跑即可分别回写各型号的 ONES 用例。
*
* 映射 key = DEVICE_CONFIG 里的设备名;值 = 该型号的 添加用例号 / 控制 step uuid(ble/wifi)。
* 控制步在两条协议超级用例里:ble→15975 / wifi→15974。
* 新型号:在此补一行即可被脚本识别。
*/
export interface DeviceAnchor {
add?: number; // 添加用例 ONES number
ctrlBle?: string; // 15975 下的 step uuid
ctrlWifi?: string; // 15974 下的 step uuid
}
// ── ONES 15975「蓝牙控制设备」step uuid → 步骤(共49步,正序,2026-06-11 从 ONES 实拉核对全部一致)──
// 1 6e4uZSVe Bot 2 5YEfmpJz Lock 3 774V8bND Curtain 4 NvpUv9Tt Meter报警 5 3Jm5FAdW Meter校温
// 6 QfYLdj8s Meter校湿 7 GkkrZpaC Humidifier 8 TNhSAuUC Bulb 9 4poyiVwD StripLight
// 10 2528azD6 吸顶灯pro 11 V15M64cP 吸顶灯lte 12 2jSFfY4k PlugMini 13 UZCtZRPy MeterPlus报警
// 14 9mheLMDJ MeterPlus校温 15 GSZv8BYm MeterPlus校湿 16 HrigrD2X Motion 17 A8C4BsCm Contact
// 18 3frMRDZj BlindTilt-V20 19 Qbm9VB72 BlindTilt-V12 20 QwnZJARA IOSensor报警 21 Ncg7BDeR IOSensor校温
// 22 k6cqKqtZ IOSensor校湿 23 QqsnPMc3 Curtain3 24 CiFPEbNS Battery循环扇 25 LnPNEJmS Lock Pro
// 26 3PmZMk1s Humidifier2 27 JBszgxRS 无电池循环扇 28 SmzuHtWi RollerShade 29 7qxA1ajE 美规净化器
// 30 R5PDp8BR 日规Table净化器 31 3wM6fW8W Curtain3-2025 32 JggzNXDo MeterPro报警 33 L967RGHa MeterPro校温
// 34 8Wzaj5pB MeterPro校湿 35 3bYsmiZG MeterProCO2报警 36 NDqRQxVx CO2校温 37 DxKG9Acs CO2校湿
// 38 3ob75cjf RGBWW灯带3 39 JVnRz7xY RGBWW落地灯 40 MKgLq1oy Relay1pm 41 A1TLxsFw Relay1
// 42 PG62s725 Relay2pm开关 43 AafJ5tj5 Relay2pm覆盖 44 E5YRm4Pg GarageDoor 45 QAHNrXrm RGBICWW灯带
// 46 AfxmoAEq RGBICWW落地灯 47 E2QCS8xy RGBIC霓虹钢丝 48 TSVKWcJ3 eu plug 49 XWmNA9UL Standing循环扇
// 注:WiFi 控制超级用例为 15974,step uuid 不同(见各 ctrlWifi)。
export const ANCHORS: Record<string, Record<string, DeviceAnchor>> = {
curtain: {
'Curtain 1A': { add: 15969, ctrlBle: '774V8bND', ctrlWifi: 'GPT3wJd9' }, // step3 Curtain
'Curtain3 2B': { add: 40955, ctrlBle: 'QqsnPMc3', ctrlWifi: 'GYtvdMTW' }, // step23 Curtain3
'BlindTilt 3C': { add: 15946, ctrlBle: '3frMRDZj', ctrlWifi: '6gv1WLKE' }, // step18 BlindTilt V20
// —— 按运行时卡名/注册名的别名(控制用例用 CURTAIN_DEVICE/BT_DEVICE 卡名取锚点,与上面旧 key 对齐)——
'Curtain Auto': { add: 15969, ctrlBle: '774V8bND', ctrlWifi: 'GPT3wJd9' }, // = Curtain 1A
'Curtain3 Auto': { add: 40955, ctrlBle: 'QqsnPMc3', ctrlWifi: 'GYtvdMTW' }, // = Curtain3 2B (step23)
'Curtain3 2025 Auto': { add: 265933, ctrlBle: '3wM6fW8W', ctrlWifi: 'VbqWg59G' }, // step31 Curtain3-2025
'Blind Tilt 42': { add: 15946, ctrlBle: '3frMRDZj', ctrlWifi: '6gv1WLKE' }, // = BlindTilt 3C (step18)
// 'Roller Shade': { add: 191100, ctrlBle: 'SmzuHtWi', ctrlWifi: 'ScBpcSfJ' },
// 'Curtain3 2025': { add: 265933, ctrlBle: '3wM6fW8W', ctrlWifi: 'VbqWg59G' },
},
lock: {
'Lock 6F': { add: 15970, ctrlBle: '5YEfmpJz', ctrlWifi: '7cEkbh4Y' }, // step2 Lock 开锁/解锁
'LockPro 7G': { add: 66694, ctrlBle: 'LnPNEJmS', ctrlWifi: 'Virku9zd' }, // step25 Lock Pro 开锁/解锁
// 以下变体 UI 相似:仅添加(控制必测无独立 step;Lock Ultra 为全新 UI,归新写)
'Lock Lite': { add: 304132 },
'Lock & Kit': { add: 51440 },
'Lock Pro & Kit': { add: 105436 },
'Lock Pro WiFi': { add: 304133 },
},
plug: {
// base Plug 仅 WiFi 必测控制(BLE 无)
'Plug 4D': { add: 15966, ctrlWifi: 'Ay79Pj23' },
'PlugMini 5E': { add: 15958, ctrlBle: '2jSFfY4k', ctrlWifi: '3nXsFW9n' },
// Plug Mini 分区(JP/US 同 PlugMini 控制 step12;EU 走 eu plug step48)——控制用例按注册名 Plug JP/US/EU 取锚点
'Plug JP': { add: 15958, ctrlBle: '2jSFfY4k', ctrlWifi: '3nXsFW9n' },
'Plug US': { add: 15958, ctrlBle: '2jSFfY4k', ctrlWifi: '3nXsFW9n' },
'Plug EU': { add: 332918, ctrlBle: 'TSVKWcJ3', ctrlWifi: 'U5z9wocr' },
'eu Plug': { add: 332918, ctrlBle: 'TSVKWcJ3', ctrlWifi: 'U5z9wocr' },
'Garage Door Opener': { add: 302289, ctrlBle: 'E5YRm4Pg', ctrlWifi: '2nRaC87F' },
// Relay Switch 有 1pm/1/2pm开关/2pm覆盖 多个物理型号,共用添加用例 302288;此处取 1PM 为代表
'Relay Switch 1PM': { add: 302288, ctrlBle: 'MKgLq1oy', ctrlWifi: 'XvFF8AK7' },
// Relay Switch 2PM 控制=双路开关 → step42 Relay2pm开关(PG62s725);控制用例按注册名 "Relay Switch 2PM" 取
'Relay Switch 2PM': { add: 302288, ctrlBle: 'PG62s725' },
// Relay Switch 1(基础款 ch48)控制 → step41 Relay1(A1TLxsFw);1PM 见上 MKgLq1oy(step40)
'Relay Switch 1': { add: 302288, ctrlBle: 'A1TLxsFw' },
},
sensor: {
'Contact Sensor 5O': { add: 15962, ctrlBle: 'A8C4BsCm', ctrlWifi: 'JKSgHHbC' },
'Motion Sensor 6P': { add: 15963, ctrlBle: 'HrigrD2X', ctrlWifi: 'N7fSHmH3' },
'Presence Sensor': { add: 332917 }, // 添加人体存在传感器(控制必测无独立 step)
// IOSensor 控制必测是历史数据报警/校正(现有 sensor_control 未覆盖)→ 仅添加
'IOSensor': { add: 35871 },
},
remote: {
'Remote 3W': { add: 15967 }, // 添加Remote验证(学习/匹配遥控器为独立 case,非本条)
},
safety_alarm: {
'Safety Alarm': { add: 332919 }, // 添加 safety alarm
},
air_purifier: {
// 添加空气净化器(基础款+table款,共用添加用例 196802);控制 step 见 air_purifier 用例双发 7qxA1ajE/R5PDp8BR
'Air Purifier': { add: 196802 },
},
humidifier: {
'Humidifier 1K': { add: 15964, ctrlBle: 'GkkrZpaC', ctrlWifi: '8tx3Rg76' },
// Evaporative Humidifier(口头"加湿器2")→ step26 Humidifier2(开关控制;若必测另指"绑温湿度计"则改此 uuid)
'Evaporative Humidifier': { add: 74104, ctrlBle: '3PmZMk1s' },
},
hub: {
// hub 无控制必测,仅添加
'Hub2 8H': { add: 21787 },
'HubMini 9I': { add: 15972 },
'HubMiniMatter 0J': { add: 65336 },
'Hub2 S3': { add: 319304 },
'Hub Mini S3': { add: 319305 },
'Hub Mini Matter S3': { add: 319303 },
'Hub Plus': { add: 15971 },
},
meter: {
// meter 控制必测(报警/校正)现有 control 未覆盖;仅锚添加。Climate Panel/Radiator 为全新 UI,归新写
'Meter 3M': { add: 15965 },
'Meter Plus': { add: 15956 },
'Meter Pro': { add: 267367 },
'Meter Pro CO2': { add: 267366 },
},
robot: {
// robot 控制必测(清扫/暂停/回充)为 WiFi,现有无 _control;仅锚添加。K11+/S20 为全新 UI,归新写
'Robot S1': { add: 15952 },
'Robot S1P': { add: 15951 },
'Robot K10+': { add: 40954 },
'Robot K10+ Pro': { add: 122737 },
'Robot K10+ Pro Combo': { add: 162261 },
'Robot S10': { add: 78369 },
},
keypad: {
// keypad 无控制必测;keypad touch UI 相似仅添加。Keypad Vision 为全新 UI,归新写
'Keypad 2V': { add: 15949 },
'Keypad Touch': { add: 15948 },
},
strip_light: {
'StripLight 9S': { add: 15959, ctrlBle: '4poyiVwD', ctrlWifi: 'QgX4dX7X' },
'RGBWW Strip Light3': { add: 301585, ctrlBle: '3ob75cjf', ctrlWifi: 'N1kzcb7S' },
'RGBICWW Strip Light': { add: 311018, ctrlBle: 'QAHNrXrm', ctrlWifi: 'MAwYyCaC' },
'RGBIC Neon Wire Rope': { add: 311020, ctrlBle: 'E2QCS8xy', ctrlWifi: '5sJcsTgi' },
'RGBIC Neon Rope': { add: 393235, ctrlWifi: 'BiEXxZDr' },
},
ceiling_light: {
'CeilingLight 7Q': { add: 15950, ctrlBle: '2528azD6', ctrlWifi: 'TcnL3gFM' }, // pro
'CeilingLight lte': { add: 15950, ctrlBle: 'V15M64cP', ctrlWifi: 'WL8KSQLb' }, // lte 与 pro 共用添加用例
'RGBWW Floor Lamp': { add: 301586, ctrlBle: 'JVnRz7xY', ctrlWifi: '2hm6sXrk' },
'RGBICWW Floor Lamp': { add: 311019, ctrlBle: 'AfxmoAEq', ctrlWifi: 'ML8CSkWX' },
'Candle Lamp': { add: 393236, ctrlWifi: 'RXm3iNLR' },
},
fan: {
'Fan 0T': { add: 122775, ctrlBle: 'JBszgxRS', ctrlWifi: 'KNyzKhn6' }, // 无电池款
'Battery Circulator Fan': { add: 48159, ctrlBle: 'CiFPEbNS', ctrlWifi: '6RC22BGo' },
'Standing Circulator Fan': { add: 393234, ctrlBle: 'XWmNA9UL' },
},
};
const curProto = (): 'ble' | 'wifi' => (process.env.PROTO === 'wifi' ? 'wifi' : 'ble');
/** 当前设备的添加锚点前缀,如 `[P0][ONES:15969]`;无映射返回空串(不打锚点)。 */
export function onesAdd(cat: string, deviceName: string): string {
const a = ANCHORS[cat]?.[deviceName];
return a?.add ? `[P0][ONES:${a.add}]` : '';
}
/**
* 平台/账号类必测项锚点(无设备维度),如 onesPlatform(15940) → `[P0][ONES:15940]`。
* 已知平台 P0 编号:注册 15940 / 忘记密码 15941 / 登出 15943 / 第三方登录 15942 / 欧区账号登录 227290。
* (普通邮箱登录、账号注销 暂无独立 P0 必测项。)
*/
export function onesPlatform(id: number): string {
return `[P0][ONES:${id}]`;
}
/** 当前设备 + 当前协议的控制锚点前缀,如 `[P0][ONES:15975#774V8bND][ble]`;无对应返回空串。 */
export function onesCtrl(cat: string, deviceName: string): string {
const a = ANCHORS[cat]?.[deviceName];
if (!a) return '';
if (curProto() === 'wifi') return a.ctrlWifi ? `[P0][ONES:15974#${a.ctrlWifi}][wifi]` : '';
return a.ctrlBle ? `[P0][ONES:15975#${a.ctrlBle}][ble]` : '';
}
/**
* 15975「蓝牙控制设备」超级用例下的 **step 锚点**(按 step uuid 直接指定),如
* onesBleStep('NvpUv9Tt') → `[P0][ONES:15975#NvpUv9Tt][ble]`。
* 用于报警条件/温湿度校准等"设置类"必测步(它们挂在 15975 而非独立用例):
* Meter报警 NvpUv9Tt / Meter校温 3Jm5FAdW / Meter校湿 QfYLdj8s(见文件头 step 清单)。
*/
export function onesBleStep(uuid: string): string {
return `[P0][ONES:15975#${uuid}][ble]`;
}
// 灯类控制:通用用例(light_feature_control/eave_light_control/color_bulb)按**卡片名/注册名**取锚点。
// 卡片名与 ANCHORS 旧 key 不一致(如 "Ceiling Light Pro" vs "CeilingLight 7Q"),故这里按卡片名子串匹配。
// ⚠️ 顺序=**长/具体在前**,避免 "Ceiling Light" 抢 "Ceiling Light Pro"、"Strip Light" 抢 "RGBWW Strip Light"。
const CARD_CTRL: Array<{ match: string; ble?: string; wifi?: string }> = [
{ match: 'Ceiling Light Pro', ble: '2528azD6', wifi: 'TcnL3gFM' }, // step10 吸顶灯pro
{ match: 'RGBWW Floor Lamp', ble: 'JVnRz7xY', wifi: '2hm6sXrk' }, // step39
{ match: 'RGBICWW Floor Lamp', ble: 'AfxmoAEq', wifi: 'ML8CSkWX' }, // step46
{ match: 'RGBWW Strip Light', ble: '3ob75cjf', wifi: 'N1kzcb7S' }, // step38 (含 "RGBWW Strip Light 3")
{ match: 'RGBICWW Strip Light', ble: 'QAHNrXrm', wifi: 'MAwYyCaC' }, // step45
{ match: 'Neon', ble: 'E2QCS8xy', wifi: 'BiEXxZDr' }, // step47 霓虹(钢丝ble/绳wifi)
{ match: 'Candle', wifi: 'RXm3iNLR' }, // 融蜡灯(WiFi)
{ match: 'Color Bulb', ble: 'TNhSAuUC' }, // step8 Bulb
{ match: 'Strip Light', ble: '4poyiVwD', wifi: 'QgX4dX7X' }, // step9 基础灯带(放 RGBWW/RGBICWW 之后)
{ match: 'Ceiling Light', ble: 'V15M64cP', wifi: 'WL8KSQLb' }, // lte(放 Pro 之后)
];
/** 灯类:按卡片名/注册名取当前协议控制锚点;命中不到返回空串(打 [P0])。 */
export function onesCtrlByCard(card: string): string {
const c = card || '';
for (const e of CARD_CTRL) {
if (!c.includes(e.match)) continue;
if (curProto() === 'wifi') return e.wifi ? `[P0][ONES:15974#${e.wifi}][wifi]` : '';
return e.ble ? `[P0][ONES:15975#${e.ble}][ble]` : '';
}
return '';
}