import { DeviceDriver } from '../../drivers/types'; import { sleep, waitForSource } from './element.helper'; import { goToProfile } from './auth.helper'; async function tapText(driver: DeviceDriver, t: string): Promise { const el = driver.platform === 'android' ? await driver.findElementRaw('-android uiautomator', `new UiSelector().text("${t}")`) : await driver.findElementRaw('name', t); if (el) { await driver.tapElement(el); return true; } return false; } /** * 进入 Manage Rooms(房间管理)列表页:Profile → Manage Homes → 第一个 home → Rooms。 * 坐标按 1080×2280(进第一个 home 行);换机型需调。 */ export async function goToManageRooms(driver: DeviceDriver): Promise { await goToProfile(driver); if (!(await tapText(driver, 'Manage Homes'))) return false; await sleep(2500); await tapText(driver, 'Got it'); // 可能的"邀请加入"提示弹框 await sleep(500); await driver.tap(540, 486); // 进第一个 home(行中心) await sleep(2500); if (!(await tapText(driver, 'Rooms'))) return false; await sleep(2500); return waitForSource(driver, 'Manage Rooms', 6000).catch(() => false) as Promise; } /** 在 Manage Rooms 页创建房间:Create Room → 输入名 → OK。返回房间是否出现在列表。 */ export async function createRoom(driver: DeviceDriver, roomName: string): Promise { // 进 Manage Rooms 首次会弹「新手引导文档」,会遮挡 Create Room → 先点 Got it 关掉(无则 tapText 返回 false,无副作用)。 await tapText(driver, 'Got it'); await sleep(800); if (!(await tapText(driver, 'Create Room'))) return false; await sleep(1500); const ed = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.EditText")'); if (!ed) return false; await driver.typeText(ed, roomName); await sleep(500); await tapText(driver, 'OK'); await sleep(2500); await tapText(driver, 'Got it'); // 创建后可能再弹引导,兜底关掉 await sleep(1000); const ok = (await driver.getSource()).includes(roomName); console.log(`创建房间 ${roomName}: ${ok}`); return ok; } /** 删除房间(清理/恢复数据):点房间 → 详情页右上角删除图标(top_bar_right_icon)→ Attention 弹框 Confirm。返回房间是否已消失。 */ export async function deleteRoom(driver: DeviceDriver, roomName: string): Promise { if (!(await tapText(driver, roomName))) return false; // 进房间详情 await sleep(2000); const icon = await driver.findElementRaw('id', 'com.theswitchbot.switchbot:id/top_bar_right_icon'); if (icon) await driver.tapElement(icon); else await driver.tap(1018, 185); // 右上角删除 await sleep(1500); await tapText(driver, 'Confirm'); // Attention 确认框 await sleep(2500); const gone = !(await driver.getSource()).includes(roomName); console.log(`删除房间 ${roomName}: ${gone ? '已删除' : '仍存在'}`); return gone; } export async function selectRoom(driver: DeviceDriver, roomName: string): Promise { if (driver.platform === 'android') { const rooms = await driver.findElementsRaw('id', 'com.theswitchbot.switchbot:id/clSelectRoom'); for (const room of rooms) { const text = await driver.getElementAttribute(room, 'text'); if (text.includes(roomName)) { await driver.tapElement(room); await sleep(500); const saveEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Save")'); if (saveEl) await driver.tapElement(saveEl); await sleep(2000); return true; } } return false; } // iOS const cells = await driver.findElementsRaw('class name', 'XCUIElementTypeCell'); for (const cell of cells) { const name = await driver.getElementAttribute(cell, 'name'); if (name.includes(roomName)) { await driver.tapElement(cell); await sleep(500); const saveEl = await driver.findElementRaw('name', 'Save'); if (saveEl) await driver.tapElement(saveEl); await sleep(2000); return true; } } return false; } export async function getCurrentRoom(driver: DeviceDriver): Promise { const source = await driver.getSource(); if (source.includes('Not in any room')) return ''; if (driver.platform === 'android') { const match = source.match(/sivDeviceRoom[\s\S]*?text="([^"]+)"/); return match ? match[1] : ''; } const roomLabel = await driver.findElementRaw('name', 'Room'); if (!roomLabel) return ''; return ''; }