Configure wifi improvements (#304)

* Add timeout to improv provisioning

* Add refresh SSIDs button

* Hide password if insecured wifi

* Bump serial sdk 2.4.0
This commit is contained in:
Paulus Schoutsen 2023-01-03 15:58:37 -05:00 committed by GitHub
parent 39ae5dc40c
commit ba85feb548
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 48 deletions

16
package-lock.json generated
View File

@ -18,7 +18,7 @@
"@material/mwc-icon-button": "^0.27.0", "@material/mwc-icon-button": "^0.27.0",
"@material/mwc-textfield": "^0.27.0", "@material/mwc-textfield": "^0.27.0",
"esptool-js": "github:espressif/esptool-js#076af269f44daa5b7823031221f39bf22124c129", "esptool-js": "github:espressif/esptool-js#076af269f44daa5b7823031221f39bf22124c129",
"improv-wifi-serial-sdk": "^2.3.0", "improv-wifi-serial-sdk": "^2.4.0",
"lit": "^2.5.0", "lit": "^2.5.0",
"pako": "^2.1.0", "pako": "^2.1.0",
"tslib": "^2.4.1" "tslib": "^2.4.1"
@ -2050,13 +2050,14 @@
} }
}, },
"node_modules/improv-wifi-serial-sdk": { "node_modules/improv-wifi-serial-sdk": {
"version": "2.3.0", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.3.0.tgz", "resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.4.0.tgz",
"integrity": "sha512-z5wiuM0uAiLL/Ifc2ZwdEBpGqpjJsUv0MS12kRqMgI01C8mn58ZSEVwoxExpOPUfX8dZL5kdrpYygqM+VfhCJQ==", "integrity": "sha512-QiWbGMZdXN4LsyiS0hml0NY9D5hpmje1092SrKcFzGTuAiHpOJOfNTalD/Zl3hAd1LuN4XJLS3JCfa6ntoV8KQ==",
"dependencies": { "dependencies": {
"@material/mwc-button": "^0.27.0", "@material/mwc-button": "^0.27.0",
"@material/mwc-circular-progress": "^0.27.0", "@material/mwc-circular-progress": "^0.27.0",
"@material/mwc-dialog": "^0.27.0", "@material/mwc-dialog": "^0.27.0",
"@material/mwc-icon-button": "^0.27.0",
"@material/mwc-list": "^0.27.0", "@material/mwc-list": "^0.27.0",
"@material/mwc-select": "^0.27.0", "@material/mwc-select": "^0.27.0",
"@material/mwc-textfield": "^0.27.0", "@material/mwc-textfield": "^0.27.0",
@ -4525,13 +4526,14 @@
"dev": true "dev": true
}, },
"improv-wifi-serial-sdk": { "improv-wifi-serial-sdk": {
"version": "2.3.0", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.3.0.tgz", "resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.4.0.tgz",
"integrity": "sha512-z5wiuM0uAiLL/Ifc2ZwdEBpGqpjJsUv0MS12kRqMgI01C8mn58ZSEVwoxExpOPUfX8dZL5kdrpYygqM+VfhCJQ==", "integrity": "sha512-QiWbGMZdXN4LsyiS0hml0NY9D5hpmje1092SrKcFzGTuAiHpOJOfNTalD/Zl3hAd1LuN4XJLS3JCfa6ntoV8KQ==",
"requires": { "requires": {
"@material/mwc-button": "^0.27.0", "@material/mwc-button": "^0.27.0",
"@material/mwc-circular-progress": "^0.27.0", "@material/mwc-circular-progress": "^0.27.0",
"@material/mwc-dialog": "^0.27.0", "@material/mwc-dialog": "^0.27.0",
"@material/mwc-icon-button": "^0.27.0",
"@material/mwc-list": "^0.27.0", "@material/mwc-list": "^0.27.0",
"@material/mwc-select": "^0.27.0", "@material/mwc-select": "^0.27.0",
"@material/mwc-textfield": "^0.27.0", "@material/mwc-textfield": "^0.27.0",

View File

@ -32,7 +32,7 @@
"@material/mwc-icon-button": "^0.27.0", "@material/mwc-icon-button": "^0.27.0",
"@material/mwc-textfield": "^0.27.0", "@material/mwc-textfield": "^0.27.0",
"esptool-js": "github:espressif/esptool-js#076af269f44daa5b7823031221f39bf22124c129", "esptool-js": "github:espressif/esptool-js#076af269f44daa5b7823031221f39bf22124c129",
"improv-wifi-serial-sdk": "^2.3.0", "improv-wifi-serial-sdk": "^2.4.0",
"lit": "^2.5.0", "lit": "^2.5.0",
"pako": "^2.1.0", "pako": "^2.1.0",
"tslib": "^2.4.1" "tslib": "^2.4.1"

View File

@ -25,3 +25,12 @@ export const chipIcon = svg`
/> />
</svg> </svg>
`; `;
export const refreshIcon = svg`
<svg viewBox="0 0 24 24">
<path
fill="currentColor"
d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"
/>
</svg>
`;

View File

@ -12,7 +12,12 @@ import "./components/ewt-select";
import "./components/ewt-list-item"; import "./components/ewt-list-item";
import "./pages/ewt-page-progress"; import "./pages/ewt-page-progress";
import "./pages/ewt-page-message"; import "./pages/ewt-page-message";
import { chipIcon, closeIcon, firmwareIcon } from "./components/svg"; import {
chipIcon,
closeIcon,
firmwareIcon,
refreshIcon,
} from "./components/svg";
import { Logger, Manifest, FlashStateType, FlashState } from "./const.js"; import { Logger, Manifest, FlashStateType, FlashState } from "./const.js";
import { ImprovSerial, Ssid } from "improv-wifi-serial-sdk/dist/serial"; import { ImprovSerial, Ssid } from "improv-wifi-serial-sdk/dist/serial";
import { import {
@ -74,8 +79,8 @@ export class EwtInstallDialog extends LitElement {
// null = not available // null = not available
@state() private _ssids?: Ssid[] | null; @state() private _ssids?: Ssid[] | null;
// -1 = custom // Name of Ssid. Null = other
@state() private _selectedSsid = -1; @state() private _selectedSsid: string | null = null;
protected render() { protected render() {
if (!this.port) { if (!this.port) {
@ -416,6 +421,10 @@ export class EwtInstallDialog extends LitElement {
error = "Unable to connect"; error = "Unable to connect";
break; break;
case ImprovSerialErrorState.TIMEOUT:
error = "Timeout";
break;
case ImprovSerialErrorState.NO_ERROR: case ImprovSerialErrorState.NO_ERROR:
// Happens when list SSIDs not supported. // Happens when list SSIDs not supported.
case ImprovSerialErrorState.UNKNOWN_RPC_COMMAND: case ImprovSerialErrorState.UNKNOWN_RPC_COMMAND:
@ -424,6 +433,9 @@ export class EwtInstallDialog extends LitElement {
default: default:
error = `Unknown error (${this._client!.error})`; error = `Unknown error (${this._client!.error})`;
} }
const selectedSsid = this._ssids?.find(
(info) => info.name === this._selectedSsid
);
content = html` content = html`
<div> <div>
Enter the credentials of the Wi-Fi network that you want your device Enter the credentials of the Wi-Fi network that you want your device
@ -439,42 +451,48 @@ export class EwtInstallDialog extends LitElement {
const index = ev.detail.index; const index = ev.detail.index;
// The "Join Other" item is always the last item. // The "Join Other" item is always the last item.
this._selectedSsid = this._selectedSsid =
index === this._ssids!.length ? -1 : index; index === this._ssids!.length
? null
: this._ssids![index].name;
}} }}
@closed=${(ev: Event) => ev.stopPropagation()} @closed=${(ev: Event) => ev.stopPropagation()}
> >
${this._ssids!.map( ${this._ssids!.map(
(info, idx) => html` (info) => html`
<ewt-list-item <ewt-list-item
.selected=${this._selectedSsid === idx} .selected=${selectedSsid === info}
value=${idx} .value=${info.name}
> >
${info.name} ${info.name}
</ewt-list-item> </ewt-list-item>
` `
)} )}
<ewt-list-item <ewt-list-item .selected=${!selectedSsid} value="-1">
.selected=${this._selectedSsid === -1}
value="-1"
>
Join other Join other
</ewt-list-item> </ewt-list-item>
</ewt-select> </ewt-select>
<ewt-icon-button @click=${this._updateSsids}>
${refreshIcon}
</ewt-icon-button>
` `
: ""} : ""}
${ ${
// Show input box if command not supported or "Join Other" selected // Show input box if command not supported or "Join Other" selected
this._selectedSsid === -1 !selectedSsid
? html` ? html`
<ewt-textfield label="Network Name" name="ssid"></ewt-textfield> <ewt-textfield label="Network Name" name="ssid"></ewt-textfield>
` `
: "" : ""
} }
${!selectedSsid || selectedSsid.secured
? html`
<ewt-textfield <ewt-textfield
label="Password" label="Password"
name="password" name="password"
type="password" type="password"
></ewt-textfield> ></ewt-textfield>
`
: ""}
<ewt-button <ewt-button
slot="primaryAction" slot="primaryAction"
label="Connect" label="Connect"
@ -701,20 +719,7 @@ export class EwtInstallDialog extends LitElement {
} }
// Scan for SSIDs on provision // Scan for SSIDs on provision
if (this._state === "PROVISION") { if (this._state === "PROVISION") {
this._ssids = undefined; this._updateSsids();
this._busy = true;
this._client!.scan().then(
(ssids) => {
this._busy = false;
this._ssids = ssids;
this._selectedSsid = ssids.length ? 0 : -1;
},
() => {
this._busy = false;
this._ssids = null;
this._selectedSsid = -1;
}
);
} else { } else {
// Reset this value if we leave provisioning. // Reset this value if we leave provisioning.
this._provisionForce = false; this._provisionForce = false;
@ -726,6 +731,41 @@ export class EwtInstallDialog extends LitElement {
} }
} }
private async _updateSsids() {
const oldSsids = this._ssids;
this._ssids = undefined;
this._busy = true;
let ssids: Ssid[];
try {
ssids = await this._client!.scan();
} catch (err) {
// When we fail on first load, pick "Join other"
if (this._ssids === undefined) {
this._ssids = null;
this._selectedSsid = null;
}
this._busy = false;
return;
}
if (oldSsids) {
// If we had a previous list, ensure the selection is still valid
if (
this._selectedSsid &&
!ssids.find((s) => s.name === this._selectedSsid)
) {
this._selectedSsid = ssids[0].name;
}
} else {
this._selectedSsid = ssids.length ? ssids[0].name : null;
}
this._ssids = ssids;
this._busy = false;
}
protected override firstUpdated(changedProps: PropertyValues) { protected override firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps); super.firstUpdated(changedProps);
this._initialize(); this._initialize();
@ -742,7 +782,7 @@ export class EwtInstallDialog extends LitElement {
return; return;
} }
if (changedProps.has("_selectedSsid") && this._selectedSsid === -1) { if (changedProps.has("_selectedSsid") && this._selectedSsid === null) {
// If we pick "Join other", select SSID input. // If we pick "Join other", select SSID input.
this._focusFormElement("ewt-textfield[name=ssid]"); this._focusFormElement("ewt-textfield[name=ssid]");
} else if (changedProps.has("_ssids")) { } else if (changedProps.has("_ssids")) {
@ -855,20 +895,21 @@ export class EwtInstallDialog extends LitElement {
this._wasProvisioned = this._wasProvisioned =
this._client!.state === ImprovSerialCurrentState.PROVISIONED; this._client!.state === ImprovSerialCurrentState.PROVISIONED;
const ssid = const ssid =
this._selectedSsid === -1 this._selectedSsid === null
? ( ? (
this.shadowRoot!.querySelector( this.shadowRoot!.querySelector(
"ewt-textfield[name=ssid]" "ewt-textfield[name=ssid]"
) as EwtTextfield ) as EwtTextfield
).value ).value
: this._ssids![this._selectedSsid].name; : this._selectedSsid;
const password = ( const password =
(
this.shadowRoot!.querySelector( this.shadowRoot!.querySelector(
"ewt-textfield[name=password]" "ewt-textfield[name=password]"
) as EwtTextfield ) as EwtTextfield | null
).value; )?.value || "";
try { try {
await this._client!.provision(ssid, password); await this._client!.provision(ssid, password, 30000);
} catch (err: any) { } catch (err: any) {
return; return;
} finally { } finally {
@ -975,6 +1016,9 @@ export class EwtInstallDialog extends LitElement {
width: calc(80vw - 48px); width: calc(80vw - 48px);
height: 80vh; height: 80vh;
} }
ewt-list-item[value="-1"] {
border-top: 1px solid #ccc;
}
`, `,
]; ];
} }