1
0
Fork 0
mirror of https://github.com/sensebox/blockly-app synced 2026-02-23 02:05:22 +01:00

ota-wizard: implement wifi selection slide (mostly)

This commit is contained in:
Norwin 2018-11-07 15:57:36 +01:00
parent f81a2de7c1
commit 7445e5a54b
4 changed files with 119 additions and 32 deletions

View file

@ -28,6 +28,7 @@
<ul style="text-align: left">
<li>has the <b>WiFi shield</b> plugged in</li>
<li>has the initial <b>OTA sketch</b> installed</li>
<li>is running</li>
</ul>
<button ion-button large clear icon-end color="primary" (click)="slides.slideNext()">
Continue
@ -63,32 +64,83 @@
<ng-container *ngIf="state.compilation == 'error'">
<h2>Error compiling your sketch.</h2>
<!-- TODO <p>{{ status }}</p> -->
<p [innerHTML]="errorMsg"></p>
</ng-container>
</ion-slide>
<!-- wifi selection -->
<ion-slide>
<h1>senseBox Wifi Selection</h1>
<pre style="text-align: left">
- Android
- select from list?
- highlight `sensebox-*` networks?
- filter by SSID name (`sensebox-*`)
- filter by distance?
- enter credentials (if necessary)
- background: connect to selected SSID
- iOS
- tell user to connect to `sensebox-*` SSID, and come back when done
</pre>
<ng-container *ngIf="state.wifiSelection == 'manual'">
<h2>Connect to your senseBox</h2>
<p>
Connect to the WiFi network that your senseBox has openened.
Because we can not do this automatically on your platform, please do this manually.
</p>
</ng-container>
<ion-grid *ngIf="state.wifiSelection != 'manual'">
<ion-row>
<ion-col col-12 col-md-6>
<ion-icon name="wifi" style="font-size: 160px"></ion-icon>
<h2>Select your senseBox</h2>
<p>
In the list, all running senseBoxes with OTA available are shown.
If you don't see yours, please make sure that it
</p>
<ul style="text-align: left">
<li>has the <b>WiFi shield</b> plugged in</li>
<li>has the initial <b>OTA sketch</b> installed</li>
<li>is running</li>
</ul>
</ion-col>
<ion-col col-12 col-md-6>
<h4>Available senseBox WiFis</h4>
<ion-list>
<ion-item *ngFor="let ssid of availableSenseboxes" (click)="connectToSensebox(ssid)">
<ion-icon name="wifi" item-start></ion-icon>
{{ ssid }}
</ion-item>
<ion-item *ngIf="state.wifiSelection == 'scanning'">
<ion-spinner item-start name="dots"></ion-spinner>
searching...
</ion-item>
<ion-item *ngIf="state.wifiSelection == 'selection' && !availableSenseboxes.length">
no senseboxes available :(
</ion-item>
<ion-item>
<ion-label>Show only senseBox WiFis</ion-label>
<!-- TODO: retrigger scan on toggle -->
<ion-toggle [(ngModel)]="filterSsids"></ion-toggle>
</ion-item>
</ion-list>
<ng-container *ngIf="state.wifiSelection == 'connecting'">
<ion-spinner item-start name="dots"></ion-spinner>
connecting...
</ng-container>
<ng-container *ngIf="state.wifiSelection == 'error'">
<h2>Error!</h2>
<p [innerHTML]="errorMsg"></p>
</ng-container>
</ion-col>
</ion-row>
</ion-grid>
</ion-slide>
<!-- upload & final status -->
<ion-slide>
<h1>Status Screen</h1>
<pre style="text-align: left">
<h2>Uploading your sketch</h2>
<ion-spinner item-start name="dots"></ion-spinner>
<!-- <pre style="text-align: left">
- background: check if sensebox upload is available
- show success or error
- instructions to restart sensebox?
</pre>
</pre> -->
</ion-slide>
</ion-slides>

View file

@ -6,6 +6,10 @@ page-ota-wizard {
}
ion-slide {
h4 {
margin-bottom: 40px;
}
img {
max-height: 50%;
max-width: 60%;

View file

@ -23,12 +23,15 @@ export class OtaWizardPage implements OnInit, OnDestroy {
onlineSub: Subscription
offlineSub: Subscription
compilationFailed: boolean
filterSsids = false // TODO: add toggle to UI?
availableSenseboxes: string[] = [] // list of SSIDs
compiledSketch = undefined
errorMsg = ''
state: OtaState = {
isOnline: false,
compiledSketch: undefined,
compilation: 'compiling',
wifiSelection: 'scanning',
}
constructor(
@ -74,7 +77,8 @@ export class OtaWizardPage implements OnInit, OnDestroy {
this.handleWifiSelection()
break
case OtaSlides.Status:
case OtaSlides.Upload:
this.slides.lockSwipeToNext(true)
break
default:
@ -82,11 +86,24 @@ export class OtaWizardPage implements OnInit, OnDestroy {
}
}
async connectToSensebox (ssid: string) {
this.state.wifiSelection = 'connecting'
try {
await this.otaWifi.connectToSensebox(ssid)
this.state.wifiSelection = 'select'
this.slides.lockSwipeToNext(false)
this.slides.slideNext()
} catch (err) {
this.state.wifiSelection = 'error'
this.errorMsg = err.message
}
}
private handleCompilation () {
this.slides.lockSwipeToNext(!this.state.compiledSketch)
this.slides.lockSwipeToNext(!this.compiledSketch)
// need to go online for compilation. compilation is retriggered via this.onlineSub
if (!this.state.compiledSketch && !this.state.isOnline) {
if (!this.compiledSketch && !this.state.isOnline) {
switch (this.otaWifi.strategy) {
case WifiStrategy.Automatic:
// TODO: auto connect to previous network, if available
@ -97,20 +114,28 @@ export class OtaWizardPage implements OnInit, OnDestroy {
}
}
private handleWifiSelection () {
private async handleWifiSelection () {
this.slides.lockSwipeToNext(true)
console.log('wifi strategy:', this.otaWifi.strategy)
this.otaWifi.findSenseboxes()
.then(console.log)
.catch(console.error)
if (this.otaWifi.strategy == WifiStrategy.Manual) {
this.state.wifiSelection = 'manual'
} else {
this.state.wifiSelection = 'scanning'
try {
this.availableSenseboxes = await this.otaWifi.findSenseboxes(this.filterSsids)
this.state.wifiSelection = 'select'
} catch (err) {
this.state.wifiSelection = 'error'
this.errorMsg = err.message
}
}
}
private compileSketch () {
// TODO: mock
this.state.compilation = 'compiling'
setTimeout(() => {
this.state.compiledSketch = 'firmware binary here..'
this.compiledSketch = 'firmware binary here..'
this.state.compilation = 'done'
this.slides.lockSwipeToNext(false)
}, 4000)
@ -119,8 +144,8 @@ export class OtaWizardPage implements OnInit, OnDestroy {
type OtaState = {
isOnline: boolean,
compiledSketch: any,
compilation: 'compiling' | 'go-online' | 'done' | 'error',
wifiSelection: 'scanning' | 'connecting' | 'select' | 'manual' | 'error',
}
// names for the slide indices for easier access
@ -128,5 +153,5 @@ enum OtaSlides {
Intro = 0,
Compilation = 1,
WifiSelection = 2,
Status = 3,
Upload = 3,
}

View file

@ -38,13 +38,17 @@ export class OtaWifiProvider {
return WifiStrategy.Manual
}
async findSenseboxes (): Promise<string> {
async findSenseboxes (filterSsids = false): Promise<string[]> {
if (this.strategy != WifiStrategy.Automatic)
throw new Error('can not search for WiFi networks on this platform')
return WifiWizard2.scan()
.then(n => n.filter(n.SSID.includes(SSID_PREFIX)))
.then(n => n.map(n => n.SSID))
.then(networks => {
if (filterSsids)
networks = networks.filter(n => n.SSID.includes(SSID_PREFIX))
return networks.map(n => n.SSID)
})
}
async connectToSensebox (ssid: string): Promise<any> {
@ -54,6 +58,8 @@ export class OtaWifiProvider {
return this.platform.is('ios')
? WifiWizard2.iOSConnectNetwork(ssid)
: WifiWizard2.connect(ssid, true)
// TODO: validate that the MCU server is available
}
async uploadFirmware (blob: ArrayBufferLike): Promise<any> {