94 lines
5.5 KiB
TypeScript
94 lines
5.5 KiB
TypeScript
/**
|
||
* Hub Mini WiFi 配网 —— 连上设备后进入 "Configure Wi-Fi" 页:
|
||
* - SSID 字段:默认预填手机当前 WiFi(如 "Deco"),需清空改填目标 SSID
|
||
* - 密码字段:hint "Enter Wi-Fi password",填密码
|
||
* - 点 Next 提交,等待联网完成
|
||
* 仅支持 2.4GHz WiFi(页面有提示)。凭据来自 config/wifi.config(env 可覆盖,默认 woanmarket/woankeji)。
|
||
*/
|
||
import { DeviceDriver } from '../../drivers/types';
|
||
import { sleep } from './element.helper';
|
||
import { getWifiCredentials, WifiCredentials } from '../../config/wifi.config';
|
||
import { navigateThroughWizard } from './navigation.helper';
|
||
|
||
const EDIT = 'new UiSelector().className("android.widget.EditText")';
|
||
|
||
/** 在 "Configure Wi-Fi" 页填 SSID + 密码并 Next;随后走完向导。creds 缺省取 config/wifi.config。 */
|
||
export async function configureHubWifi(driver: DeviceDriver, creds?: WifiCredentials): Promise<void> {
|
||
const { ssid, password } = creds || getWifiCredentials();
|
||
|
||
// 等 "Configure Wi-Fi" 页出现(文本判定,跨平台)。BLE 连接较慢(relay 后约 24s 连上、27s 出页),窗口要够长(~37s)。
|
||
let onWifiPage = false;
|
||
for (let i = 0; i < 25; i++) {
|
||
const src = await driver.getSource();
|
||
if (/Configure Wi-?Fi|Wi-?Fi password|配置 ?Wi-?Fi/i.test(src)) { onWifiPage = true; break; }
|
||
await driver.dismissPopupIfPresent();
|
||
await sleep(1500);
|
||
}
|
||
if (!onWifiPage) { console.log('WARN: 未到达 Configure Wi-Fi 页,跳过配网'); return; }
|
||
|
||
if (driver.platform === 'android') {
|
||
// Android:SSID/密码都是 EditText,直接定位元素 clear + type
|
||
const eds = await driver.findElementsRaw('-android uiautomator', EDIT);
|
||
if (eds.length < 2) { console.log('WARN: 未找到 SSID/密码输入框,跳过配网'); return; }
|
||
let ssidEl = eds[0], pwdEl = eds[1];
|
||
try { const t0 = (await driver.getElementAttribute(eds[0], 'text')) || ''; if (/password|密码/i.test(t0)) { pwdEl = eds[0]; ssidEl = eds[1]; } } catch { /* 默认顺序 */ }
|
||
await driver.clearText(ssidEl).catch(() => {});
|
||
await driver.typeText(ssidEl, ssid); await sleep(500);
|
||
await driver.typeText(pwdEl, password); await sleep(500);
|
||
try { await driver.goBack(); } catch { /* 收键盘 */ }
|
||
await sleep(500);
|
||
} else {
|
||
// iOS:SSID/密码框是自绘控件、无障碍不可见 → 按坐标点 + 模拟键盘键入(/wda/keys)。
|
||
// 坐标按 iPhone 14 Pro(393×852pt):SSID≈(118,358)、密码≈(118,443);换机型需调。
|
||
// 重要:SSID 预填手机当前 WiFi(如 Deco),聚焦**不会**自动全选,必须先清空——双击选中该词再键入替换;
|
||
// 最后必须用键盘 "Return" 收起键盘,否则 Next 被键盘挡住点不到。
|
||
const d = driver as any;
|
||
await d.tap(118, 358); await sleep(800); // 聚焦 SSID
|
||
await d.doubleTap(118, 358); await sleep(700); // 双击选中预填值(单词)
|
||
await d.sendKeys(['\b']); await sleep(300); // 删除选中(退格)
|
||
await d.sendKeys([ssid]); await sleep(800); // 键入目标 SSID
|
||
await d.tap(118, 443); await sleep(800); // 聚焦密码(通常为空)
|
||
await d.sendKeys([password]); await sleep(800);
|
||
const ret = await driver.findElementRaw('name', 'Return').catch(() => null);
|
||
if (ret) { await driver.tapElement(ret); await sleep(1000); } // 收起键盘
|
||
}
|
||
console.log(`Hub WiFi 配网:SSID="${ssid}" 密码已填,提交...`);
|
||
|
||
// 点 Next(iOS 名为 Next;Android text=Next)
|
||
const next = driver.platform === 'android'
|
||
? await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Next")')
|
||
: await driver.findElementRaw('name', 'Next');
|
||
if (next) await driver.tapElement(next);
|
||
|
||
// 提交后是多步配网过程:连接 WiFi → 验证成功 → 设备配网成功 → 跳添加成功页,过程较久。
|
||
// 期间都是进度页,**不要乱点按钮**(误点会打断配网),只被动等"成功"强标志出现 + 关弹框。
|
||
const SUCCESS = [
|
||
'added successfully', 'Added successfully', 'Start Using', 'Use now', 'Pick a room',
|
||
'Set up complete', 'Setup complete', 'configured successfully', 'connected to',
|
||
'添加成功', '配网成功', '连接成功', '设置完成',
|
||
];
|
||
const FAIL = ['Failed', 'failed', 'incorrect', 'wrong', 'Unable', '失败', '密码错误', 'try again', 'Try Again'];
|
||
let reached = false;
|
||
for (let t = 0; t < 30; t++) { // 最多 ~90s 等配网过程
|
||
const src = await driver.getSource();
|
||
if (SUCCESS.some((k) => src.includes(k))) { console.log(`Hub 配网成功(到结果页, +${t * 3}s)`); reached = true; break; }
|
||
if (FAIL.some((k) => src.includes(k))) {
|
||
const vis = (src.match(/text="([^"]+)"/g) || []).map((x) => x.replace(/text="|"/g, '')).filter(Boolean).slice(0, 12).join(' | ');
|
||
console.log(`WARN: Hub 配网疑似失败(+${t * 3}s)。页面:${vis}`);
|
||
break;
|
||
}
|
||
if (t % 3 === 0) { // 每 ~9s 记一次当前阶段,便于排查"连接/验证/配网"卡在哪
|
||
const vis = (src.match(/text="([^"]+)"/g) || []).map((x) => x.replace(/text="|"/g, '')).filter(Boolean).slice(0, 8).join(' | ');
|
||
console.log(` 配网进行中 +${t * 3}s: ${vis}`);
|
||
}
|
||
await driver.dismissPopupIfPresent();
|
||
await sleep(3000);
|
||
}
|
||
if (!reached) console.log('WARN: 未等到 Hub 配网成功页(可能 WiFi 不可达/非2.4G/密码错,或过程超 90s)');
|
||
|
||
// 到结果页后走完结尾向导(Start Using / Done / 房间等)
|
||
await driver.dismissPopupIfPresent();
|
||
await navigateThroughWizard(driver, ['Use now', 'Start Using', 'Done', 'Got it', 'OK', 'Skip', 'Next'], 8);
|
||
}
|
||
|