AI_UIAutomation/config/relay.config.ts

408 lines
19 KiB
TypeScript

/**
* 继电器板通道映射 + 物理按键动作配置(参数化,勿在脚本里写死通道号/时长)。
*
* 每路继电器接到某设备的某个物理按键或电源。这里把「设备 → 按键名 → 通道号」以及
* 「进入配对模式要按哪些键、按多久」集中配置,脚本只引用语义名(如 'remote' 的 'pairing')。
*
* **按平台区分通道**:Android 与 iOS 是两套真机,同一设备的按键接在继电器板的不同通道上。
* 通道号写成 { android, ios };动作逻辑(按哪些键/按多久)两端共用。平台取 process.env.PLATFORM
* (与 config/app.config、设备名注册表一致,默认 ios)。
*
* 实测接线(Android,2026-06):ch33=meter 主键、ch34=remote 凸键、ch35=remote 凹键。
* iOS 通道待接线后填入(留空则在 iOS 下调用会报清晰错误)。
* 时长可被 env 覆盖:RELAY_HOLD_MS_<DEVICE>_<ACTION>(全大写)。
*/
/** 通道号:两端相同写数字;两端不同写 { android, ios }。 */
export type ChannelSpec = number | { android?: number; ios?: number };
export interface RelayAction {
buttons: string[]; // 同时按下的按键名(引用本设备 buttons 的 key);单键即数组里一个
holdMs: number; // 按住毫秒数
desc?: string;
}
export interface RelayDeviceConfig {
buttons: Record<string, ChannelSpec>; // 按键名 → 通道(可按平台)
actions?: Record<string, RelayAction>;
/** 该设备接在哪块继电器板(MODBUS 设备 ID/板号)。缺省=1。现有接线全在 1 号板,新增板上的设备标 board: 2。 */
board?: number;
}
export const RELAY_MAP: Record<string, RelayDeviceConfig> = {
meter: {
buttons: { main: { android: 32 , ios: 33 } },
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住主键进入添加模式' },
},
},
remote: {
buttons: {
convex: { android: 26 , ios: 42 }, // 凸键
concave: { android: 25 , ios: 43 }, // 凹键
},
actions: {
pairing: { buttons: ['convex', 'concave'], holdMs: 2000, desc: '同时按凸键+凹键 2s 进入添加模式(切换式:按一次进、再按退,勿重按)' },
},
},
outdoor_meter: {
buttons: { main: { android: 28 , ios: 38 } },
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住主键 2s 进入添加模式' },
},
},
motion: {
buttons: { main: { android: 29 , ios: 34 } }, // Motion Sensor 配对键(电池仓内按键)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键 2s 进入添加模式' },
},
},
curtain3: {
buttons: {
power: { android: 27 , ios: 46}, // 开关按钮
track: { android: 38 /*, ios: <填> */ }, // 控制轨道按钮(控制用,不参与配对)
},
actions: {
pairing: { buttons: ['power'], holdMs: 2000, desc: '按住开关按钮 2s 进入添加模式' },
},
},
curtain: {
buttons: { power: { android: 24 , ios: 63 } }, // 开关按钮
actions: {
pairing: { buttons: ['power'], holdMs: 2000, desc: '按住开关按钮 2s 进入添加模式' },
},
},
hub: {
buttons: { main: { android: 23 , ios: 37} }, // Hub Mini 主键
actions: {
pairing: { buttons: ['main'], holdMs: 4000, desc: '按住主键 4s 进入添加模式(Hub Mini;指引页写3s,实测需4s)' },
},
},
hub3: {
buttons: {
off: { android: 9 /*, ios: <填> */ }, // 关机键(ch9)
on: { android: 10 /*, ios: <填> */ }, // 开机键(ch10)
},
actions: {
pairing: { buttons: ['off', 'on'], holdMs: 3000, desc: '同时长按 off+on 键(ch9+10)3s 进入添加模式(Hub 3,WiFi)' },
},
},
hub_plus: {
buttons: {
a: { android: 14 , ios: 47 }, // Hub Plus 配对键1(ch14,与 K20+/S10 共用,物理同时只接一个)
b: { android: 15 , ios: 48 }, // Hub Plus 配对键2(ch15)
},
actions: {
pairing: { buttons: ['a', 'b'], holdMs: 4000, desc: '同时长按 ch14+15 4s 进入添加模式(Hub Plus,WiFi;时长待实测)' },
},
},
relay_switch: {
buttons: { main: { android: 48 /*, ios: <填> */ } }, // Relay Switch 1 配对键(ch48,WiFi 产品)
actions: {
// 长按配对键 3s 使 Relay Switch 进入广播/添加模式(实测 3s)
pairing: { buttons: ['main'], holdMs: 3000, desc: '长按配对键 3s 使 Relay Switch 进入广播/添加模式(WiFi)' },
},
},
relay_switch_1pm: {
buttons: { main: { android: 59 /*, ios: <填> */ } }, // Relay Switch 1PM 配对键(ch59;入口二级型号选"Relay Switch 1PM")
actions: {
pairing: { buttons: ['main'], holdMs: 3000, desc: '长按配对键 3s 进入添加模式(Relay Switch 1PM,ch59)' },
},
},
relay_switch_2pm: {
buttons: { main: { android: 58 /*, ios: <填> */ } }, // Relay Switch 2PM 配对键(ch58;入口二级型号选"Relay Switch 2PM")
actions: {
pairing: { buttons: ['main'], holdMs: 3000, desc: '长按配对键 3s 进入添加模式(Relay Switch 2PM,ch58)' },
},
},
water: {
buttons: { main: { android: 22 , ios: 40 } }, // Water Detector(水浸)配对键
actions: {
// ⚠️ 配对时长待实测;先按 2s 试
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键进入添加模式(水浸,待实测确认时长)' },
},
},
weather_station: {
buttons: { main: { android: 13 /*, ios: <填> */ } }, // Weather Station(天气站)配对键(ch13,流程同水浸)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键 2s 进入添加模式(天气站,流程同水浸;待实测确认时长)' },
},
},
urc: {
buttons: {
off: { android: 20 /*, ios: <填> */ }, // 关机键(ch20)
on: { android: 21 /*, ios: <填> */ }, // 开机键(ch21)
},
actions: {
pairing: { buttons: ['off', 'on'], holdMs: 4000, desc: '同时长按 off+on 键(ch20+21)4s 进入添加模式(Universal Remote 万能遥控器)' },
},
},
hubMatter: {
buttons: { main: { android: 23 /*, ios: <填> */ } }, // Hub Mini Matter 主键(添加入口仍是 "Hub Mini")
actions: {
// ⚠️ 配对时长待实测;先沿用 Hub Mini 的 4s
pairing: { buttons: ['main'], holdMs: 4000, desc: '按住主键进入添加模式(Hub Mini Matter,添加入口=Hub Mini;待实测确认时长)' },
},
},
contact: {
buttons: { main: { android: 47 , ios: 45 } }, // Contact Sensor 配对键(ch47,2026-06 由 44 改;与 plug_mini_eu 同口,同时只接一个)
actions: {
// 实测:长按 6s 进配对(2s/4s 不够,2026-06 确认)
pairing: { buttons: ['main'], holdMs: 6000, desc: '长按配对键 6s 进入添加模式(Contact Sensor)' },
},
},
meter_plus: {
buttons: { main: { android: 31 , ios: 44 } }, // Meter Plus 主键
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住主键 2s 进入添加模式(Meter Plus)' },
},
},
find_card: {
buttons: { main: { android: 30 , ios: 64 } }, // Wallet Finder Card 配对键
actions: {
// ⚠️ 配对时长待实测
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键进入添加模式(Wallet Finder Card,待实测确认时长)' },
},
},
plug_mini: {
buttons: { main: { android: 1 /*, ios: <填> */ } }, // Plug Mini (JP) 配对键
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键2s 进入添加模式(Plug Mini JP,品类"Plug Mini (JP)")' },
},
},
plug_mini_us: {
buttons: { main: { android: 2 /*, ios: <填> */ } }, // Plug Mini (US) 配对键
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键2s 进入添加模式(Plug Mini US,品类"Plug Mini (US)")' },
},
},
safety_alarm: {
buttons: { main: { android: 3 , ios:49 } }, // Safety Alarm 配对键(ch3,BLE 无WiFi,流程近 Find Card)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键 2s 进入添加模式(Safety Alarm,BLE无WiFi;选品类后 Disclaimers→Next 再 Connect Device)' },
},
},
meter_pro: {
buttons: { main: { android: 4 , ios: 36 } }, // Meter Pro (CO2) 配对键(ch4,纯BLE,与 meter 同流程、入口品类名不同)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住主键 2s 进入添加模式(Meter Pro CO2)' },
},
},
presence_sensor: {
buttons: { main: { android: 5 , ios: 35 } }, // Presence Sensor 配对键(ch5,与 Motion Sensor 同品类组/同流程,入口名不同)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键 2s 进入添加模式(Presence Sensor)' },
},
},
curtain3_2025: {
buttons: { power: { android: 6 , ios: 39 } }, // Curtain 3 2025 开关键(ch6,入口品类=Curtain;校准流程待实测 curtain/curtain3)
actions: {
pairing: { buttons: ['power'], holdMs: 2000, desc: '按住开关键 2s 进入添加模式(Curtain 3 2025)' },
},
},
plug_mini_eu: {
buttons: { main: { android: 7 /*, ios: <填> */ } }, // Plug Mini (EU) 配对键(ch7,WiFi 产品,品类“Plug Mini (EU)”)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键2s 进入添加模式(Plug Mini EU,品类“Plug Mini (EU)”)' },
},
},
color_bulb: {
buttons: { main: { android: 2 /*, ios: <填> */ } }, // Color Bulb 配对键(ch2,与 plug_mini_us 共用通道;物理同时只接一个)
actions: {
// 特殊:点一次→等2s→再点一次 进配对(非单次长按)。脚本用 pressButton 两次实现。
pairing: { buttons: ['main'], holdMs: 400, desc: '点一次→等2s→再点一次 进添加模式(Color Bulb,WiFi 产品)' },
},
},
ceiling_light_pro: {
buttons: { main: { android: 1 /*, ios: <填> */ } }, // 吸顶灯 Pro 配对键(ch1,与 plug_mini JP 共用通道;同时只接一个)
actions: {
// 同 Color Bulb:点一次→等2s→再点一次 进配对(脚本用 pressButton 两次)。
pairing: { buttons: ['main'], holdMs: 400, desc: '点一次→等2s→再点一次 进添加模式(吸顶灯 Pro,WiFi 产品)' },
},
},
strip_light: {
buttons: { main: { android: 33 , ios: 41 } }, // Strip Light(灯带)配对键(ch33,灯类,WiFi 产品)
actions: {
// 长按 2s 进配对(灯带,不同于 color bulb 的两次点按)。
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(Strip Light 灯带,WiFi)' },
},
},
doorbell: {
buttons: {
talk: { android: 36 /*, ios: <填> */ }, // 通话键
hangup: { android: 37 /*, ios: <填> */ }, // 挂断键
},
actions: {
pairing: { buttons: ['talk', 'hangup'], holdMs: 5000, desc: '同时长按 通话+挂断 键 5s 进入添加模式(门铃 Video Doorbell,WiFi)' },
},
},
outdoor_ptc: {
buttons: { main: { android: 36 , ios: 50 } }, // Outdoor PTC 配对键(ch36;与 doorbell.talk 同口,物理同时只接一个)
actions: {
// ⚠️ 配对时长待实测;先按 2s 试(流程参考水浸 Water Detector:按键进配对 + WiFi 配网)
pairing: { buttons: ['main'], holdMs: 2000, desc: '按住配对键 2s 进入添加模式(Outdoor PTC,入口品类 Outdoor Pan/Tilt Cam 3K;待实测确认时长)' },
},
},
keypad: {
buttons: {
unlock: { android: 35 /*, ios: <填> */ }, // ch35=上锁键(配对用,历史名 unlock)
confirm: { android: 34 /*, ios: <填> */ }, // ch34=确定键
k1: { android: 51 /*, ios: <填> */ }, // 数字键 1-6 = ch51-56(密码输入用)
k2: { android: 52 /*, ios: <填> */ },
k3: { android: 53 /*, ios: <填> */ },
k4: { android: 54 /*, ios: <填> */ },
k5: { android: 55 /*, ios: <填> */ },
k6: { android: 56 /*, ios: <填> */ },
},
actions: {
pairing: { buttons: ['unlock', 'confirm'], holdMs: 5000, desc: '同时长按 ch35+ch34 5s 进入添加模式(Keypad Vision Pro,BLE)' },
// 输入密码 123456 + 确定:脚本依次短按 k1..k6 再短按 confirm(ch34)。
},
},
keypad_touch: {
buttons: {
key1: { android: 39 /*, ios: <填> */ },
key2: { android: 40 /*, ios: <填> */ },
},
actions: {
pairing: { buttons: ['key1', 'key2'], holdMs: 3000, desc: '同时长按 39+40 键 3s 进入添加模式(Keypad Touch,BLE)' },
},
},
neon_light: {
buttons: { main: { android: 41 /*, ios: <填> */ } }, // 炫彩霓虹灯(RGBIC Neon Rope)配对键(ch41,灯类WiFi,同灯带流程)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(炫彩霓虹灯,WiFi)' },
},
},
floor_lamp: {
buttons: { main: { android: 42 /*, ios: <填> */ } }, // 落地灯(Floor Lamp)配对键(ch42,灯类WiFi)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(落地灯 Floor Lamp,WiFi)' },
},
},
strip_light_3: {
buttons: { main: { android: 45 /*, ios: <填> */ } }, // 灯带3(RGBWW Strip Light 3)配对键(ch45,灯类WiFi;流程同落地灯)
actions: {
pairing: { buttons: ['main'], holdMs: 4000, desc: '长按配对键 4s 进入添加模式(灯带3 RGBWW strip light 3,WiFi;流程同落地灯)' },
},
},
color_floor_lamp: {
buttons: { main: { android: 44 /*, ios: <填> */ } }, // 炫彩落地灯(RGBIC Floor Lamp)配对键(ch44,灯类WiFi)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(炫彩落地灯 RGBIC Floor Lamp,WiFi)' },
},
},
eave_light: {
buttons: { main: { android: 38 /*, ios: <填> */ } }, // 屋檐灯(Permanent Outdoor Lights)配对键(ch38,灯类WiFi;与 curtain3.track 共用通道,物理同时只接一个)
actions: {
pairing: { buttons: ['main'], holdMs: 4000, desc: '长按配对键 4s 进入添加模式(屋檐灯 Permanent Outdoor Lights,WiFi;流程同落地灯 Floor Lamp)' },
},
},
candle_lamp: {
buttons: { main: { android: 57 /*, ios: <填> */ } }, // 融蜡灯(Candle Warmer Lamp)配对键(ch57,灯类WiFi;流程同屋檐灯)
actions: {
pairing: { buttons: ['main'], holdMs: 5000, desc: '长按配对键 5s 进入添加模式(融蜡灯 Candle Warmer Lamp,WiFi;流程同屋檐灯)' },
},
},
aihub: {
buttons: { main: { android: 43 /*, ios: <填> */ } }, // AI Hub 配对键(ch43,与 Hub Mini 同口;按一下即可)
actions: {
pairing: { buttons: ['main'], holdMs: 400, desc: '按一下配对键(AI Hub,单次短按)' },
},
},
robot_s1p: {
buttons: {
a: { android: 11 /*, ios: <填> */ }, // 扫地机 S1 Plus 配对键1(ch11)
b: { android: 12 /*, ios: <填> */ }, // 扫地机 S1 Plus 配对键2(ch12)
},
actions: {
pairing: { buttons: ['a', 'b'], holdMs: 5000, desc: '同时长按 ch11+12 5s 进入添加模式(扫地机 S1 Plus;在添加向导第二步按)' },
},
},
robot_k20p: {
buttons: {
a: { android: 13 /*, ios: <填> */ }, // 扫地机 K20+ 配对键1(ch13)
b: { android: 14 /*, ios: <填> */ }, // 扫地机 K20+ 配对键2(ch14)
},
actions: {
pairing: { buttons: ['a', 'b'], holdMs: 5000, desc: '同时长按 ch13+14 5s 进入添加模式(扫地机 K20+;流程同 S1 Plus,向导第二步按)' },
},
},
robot_s10: {
buttons: {
a: { android: 17 /*, ios: <填> */ }, // 扫地机 S10 配对键1(ch17)
b: { android: 18 /*, ios: <填> */ }, // 扫地机 S10 配对键2(ch18)
},
actions: {
pairing: { buttons: ['a', 'b'], holdMs: 5000, desc: '同时长按 ch17+18 5s 进入添加模式(扫地机 S10;入口 Floor Cleaning Robot S10,流程同水浸串口配对+配网)' },
},
},
ai_art_frame: {
buttons: { main: { android: 46 /*, ios: <填> */ } }, // AI Art Frame 配对键(ch46,流程同 AI Hub;长按 3s 进添加模式)
actions: {
pairing: { buttons: ['main'], holdMs: 3000, desc: '长按配对键 3s 进入添加模式(AI Art Frame,流程同 AI Hub)' },
},
},
kata: {
buttons: {
key1: { android: 17 /*, ios: <填> */ },
key2: { android: 18 /*, ios: <填> */ },
},
actions: {
pairing: { buttons: ['key1', 'key2'], holdMs: 3000, desc: '同时长按 17+18 键 3s 进入添加模式(KATA Friends,流程同 AI Hub)' },
},
},
humidifier2: {
buttons: { main: { android: 63 , ios: 62 } }, // Evaporative Humidifier(口头"加湿器2")配对键(ch63,带 WiFi 模块)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(Evaporative Humidifier,WiFi,实测2s可用)' },
},
},
air_purifier: {
buttons: { main: { android: 62 , ios: 32 } }, // 空气净化器(Air Purifier)配对键(ch62,带 WiFi 模块;流程同加湿器2)
actions: {
pairing: { buttons: ['main'], holdMs: 2000, desc: '长按配对键 2s 进入添加模式(Air Purifier,WiFi;流程同 Evaporative Humidifier)' },
},
},
};
function currentPlatform(): 'android' | 'ios' {
return (process.env.PLATFORM || 'ios').toLowerCase() === 'android' ? 'android' : 'ios';
}
/** 解析某按键在当前平台的通道号。iOS 未单独配通道时,回退到 android(两端复用同一套设备/通道时用)。 */
function channelOf(device: string, button: string): number {
const spec = RELAY_MAP[device]?.buttons?.[button];
if (spec == null) throw new Error(`relay 配置无 '${device}.${button}'(config/relay.config.ts)`);
if (typeof spec === 'number') return spec;
const plat = currentPlatform();
const ch = spec[plat] ?? spec.android; // iOS 缺省回退 android(先复用 Android 配置)
if (ch == null) throw new Error(`'${device}.${button}' 未配置 ${plat}(且无 android 回退)的通道(config/relay.config.ts)`);
return ch;
}
/** 取设备所在板号(MODBUS 设备 ID);缺省 1(现有接线全在 1 号板)。 */
export function resolveRelayBoard(device: string): number {
return RELAY_MAP[device]?.board ?? 1;
}
/** 取设备某动作要触发的通道列表 + 时长 + 板号(按当前平台解析通道;env 可覆盖时长)。 */
export function resolveRelayAction(
device: string,
action: string
): { channels: number[]; holdMs: number; desc?: string; board: number } {
const dev = RELAY_MAP[device];
if (!dev) throw new Error(`relay 配置无设备 '${device}'(config/relay.config.ts)`);
const act = dev.actions?.[action];
if (!act) throw new Error(`设备 '${device}' 无动作 '${action}'`);
const channels = act.buttons.map((b) => channelOf(device, b));
const envKey = `RELAY_HOLD_MS_${device.toUpperCase()}_${action.toUpperCase()}`;
const holdMs = process.env[envKey] ? parseInt(process.env[envKey] as string, 10) : act.holdMs;
return { channels, holdMs, desc: act.desc, board: resolveRelayBoard(device) };
}
/** 取设备某按键在当前平台的通道号。 */
export function resolveRelayButton(device: string, button: string): number {
return channelOf(device, button);
}