Skip to content

Commit

Permalink
- Add mdns and ngx-electron plugin
Browse files Browse the repository at this point in the history
- Add electron-rebuild to dev depends so that electron can be rebuilt with the installed node
- Fix setTimeout and setInstance to with with Node modules (required for mdns)
- Reduce the version on node as electron needs to be on the same version for this to work
- Change order in on boarding wizard to select API first
- Use mdns to detect and list octoprint instances (WIP need to figure out min version required)
- Auto set Printer name if a detected install if found.

I'm trying to reduce input and the need for a keyboard during onboarding.  Obviously this is just the first step as the API key still needs to be inputed.  But it's still a start.

Follow Issue UnchartedBull#921 for more info on the changes.
  • Loading branch information
TheSin- committed Aug 29, 2020
1 parent 8f4bf95 commit 8554b88
Show file tree
Hide file tree
Showing 9 changed files with 595 additions and 60 deletions.
457 changes: 451 additions & 6 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
"electron-store": "^6.0.0",
"got": "^11.5.2",
"lodash": "^4.17.20",
"mdns": "^2.5.1",
"ngx-electron": "^2.2.0",
"ngx-spinner": "^10.0.1",
"progress-stream": "^2.0.0",
"rxjs": "~6.6.2",
Expand All @@ -95,12 +97,13 @@
"@angular/language-service": "~10.0.11",
"@types/ajv": "^1.0.0",
"@types/lodash": "^4.14.159",
"@types/node": "^14.6.0",
"@types/node": "~12.12.54",
"@typescript-eslint/eslint-plugin": "^3.9.1",
"@typescript-eslint/parser": "^3.9.1",
"codelyzer": "^6.0.0",
"electron": "^9.2.1",
"electron-builder": "^22.8.0",
"electron-rebuild": "^2.0.0",
"electron-reload": "^1.5.0",
"eslint": "7.7.0",
"eslint-plugin-import": "^2.22.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FaIconLibrary, FontAwesomeModule } from "@fortawesome/angular-fontaweso
import { fas } from "@fortawesome/free-solid-svg-icons";
import { RoundProgressModule } from "angular-svg-round-progressbar";
import { NgxSpinnerModule } from "ngx-spinner";
import { NgxElectronModule } from 'ngx-electron';

import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app.routing.module";
Expand Down Expand Up @@ -65,6 +66,7 @@ import { URLSafePipe } from "./url.pipe";
FormsModule,
FontAwesomeModule,
NgxSpinnerModule,
NgxElectronModule,
BrowserAnimationsModule,
MatRippleModule,
],
Expand Down
78 changes: 51 additions & 27 deletions src/app/config/no-config/no-config.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
Thanks for choosing OctoDash <fa-icon [icon]="['fas', 'smile']"></fa-icon>
</span>
</div>
<div *ngIf="page === 1">
<div *ngIf="page === 3">
<span class="no-config__text">
First, tell me some facts about your printer so I can personalize OctoDash for you.
</span>
Expand All @@ -54,7 +54,7 @@
Wiki.
</div>
</div>
<div *ngIf="page === 2">
<div *ngIf="page === 4">
<span class="no-config__text">
I also need some information about your extruder.
</span>
Expand Down Expand Up @@ -92,33 +92,54 @@
</div>
</form>
</div>
<div *ngIf="page === 3">
<div *ngIf="page === 1">
<span class="no-config__text">
Now I need to know something about your OctoPrint setup, so I can talk to your printer.
</span>
<form class="no-config__form">
<label for="octoprintURLName" class="no-config__input-label">URL:</label>
<span class="no-config__input-prefix">http://</span>
<input
type="text"
id="octoprintURLName"
<label for="octoprintInstance" class="no-config__input-label">Instance:</label>
<select
id="octoprintInstance"
class="no-config__input"
[(ngModel)]="this.config.octoprint.urlSplit.url"
name="octoprintURLName"
required
style="width: 42.5vw;"
/>
:
<input
type="text"
id="octoprintURLPort"
class="no-config__input"
[(ngModel)]="this.config.octoprint.urlSplit.port"
name="octoprintURLPort"
required
style="width: 14vw;"
/>
<br />
[(ngModel)]="opInstance"
name="octoprintInstance"
style="width: 67vw;"
size="3"
require
>
<option *ngFor="let node of objectvalues(octoprintNodes)" [ngValue]="node" [disabled]="node.disable">{{ node.display }}</option>
</select>
</form>
</div>
<div *ngIf="page === 2">
<span class="no-config__text">
Now I need to know something about your OctoPrint setup, so I can talk to your printer.
</span>
<form class="no-config__form">
<div *ngIf="manualEntry">
<label for="octoprintURLName" class="no-config__input-label">URL:</label>
<span class="no-config__input-prefix">http://</span>
<input
type="text"
id="octoprintURLName"
class="no-config__input"
[(ngModel)]="this.config.octoprint.urlSplit.url"
name="octoprintURLName"
required
style="width: 42.5vw;"
/>
:
<input
type="text"
id="octoprintURLPort"
class="no-config__input"
[(ngModel)]="this.config.octoprint.urlSplit.port"
name="octoprintURLPort"
required
style="width: 14vw;"
/>
<br />
</div>
<label for="accessToken" class="no-config__input-label">API Key:</label>
<input
type="text"
Expand All @@ -130,8 +151,11 @@
required
/>
</form>
<span class="no-config__text">
{{ this.opApiMsg }}
</span>
</div>
<div *ngIf="page === 4">
<div *ngIf="page === 5">
<span class="no-config__text">
And now personalize me to your liking.
</span>
Expand Down Expand Up @@ -160,7 +184,7 @@
</div>
</form>
</div>
<div *ngIf="page === 5">
<div *ngIf="page === 6">
<span class="no-config__text">
What plugins are you running?
</span>
Expand Down Expand Up @@ -224,7 +248,7 @@
</div>
</div>
</div>
<div *ngIf="page === 6">
<div *ngIf="page === 7">
<span class="no-config__text">
Great! I'll check everything.
</span>
Expand Down
103 changes: 82 additions & 21 deletions src/app/config/no-config/no-config.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { HttpClient, HttpErrorResponse, HttpHeaders } from "@angular/common/http
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";

import { ElectronService } from 'ngx-electron';

import { Config, ConfigService } from "../config.service";

@Component({
Expand All @@ -10,27 +12,40 @@ import { Config, ConfigService } from "../config.service";
styleUrls: ["./no-config.component.scss"],
})
export class NoConfigComponent implements OnInit {
public page = 0;
public totalPages = 6;
public page: number = 0;
public totalPages: number = 7;

private configUpdate: boolean;
public config: Config;
public configErrors: string[];
public configValid: boolean;
public configSaved: string;

public octoprintConnection: boolean;
public objectvalues = Object.values;
public octoprintNodes: any = {
'other': {
'display': 'Other (> 1.4.0)',
'name': 'other',
'version': '1.4.0',
'url': 'other',
'disable': false
}
};
public opInstance: any = this.octoprintNodes['other'];
public opApiMsg: string = '';
public manualEntry: boolean = true;
public octoprintConnection: boolean = false;
public octoprintConnectionError: string;

public constructor(private configService: ConfigService, private http: HttpClient, private router: Router) {
public constructor(private configService: ConfigService, private http: HttpClient, private router: Router, private _electronService: ElectronService) {
this.configUpdate = this.configService.isUpdate();
console.log(this.configUpdate);
if (this.configUpdate) {
this.config = configService.getCurrentConfig();
} else {
this.config = {
octoprint: {
url: "http://localhost:5000/api/",
url: "http://localhost:80/api/",
accessToken: "",
},
printer: {
Expand Down Expand Up @@ -137,25 +152,46 @@ export class NoConfigComponent implements OnInit {

public ngOnInit(): void {
this.changeProgress();

const mdns = this._electronService.remote.require('mdns');
const browser = mdns.createBrowser(mdns.tcp('octoprint'));
browser.on('serviceUp', service => {
var node = {
'display': service.name.match(/"([^"]+)"/)[1] + ' (' + service.txtRecord.version + ')',
'name': service.name.match(/"([^"]+)"/)[1],
'version': service.txtRecord.version,
'url': service.host.replace(/\.$/, '') + ":" + service.port + service.txtRecord.path.replace(/\/$/, '') + "/api/",
// Compare version to make sure it meets the requirement
'disable': false
};

this.octoprintNodes[service.host.replace(/\.$/, '').replace('.', '_')] = node;
});
browser.on('serviceDown', service => {
delete this.octoprintNodes[service.host.replace(/\.$/, '').replace('.', '_')];
});
browser.start();
}

public testOctoprintAPI(): boolean {
public async testOctoprintAPI(): Promise<any> {
const httpHeaders = {
headers: new HttpHeaders({
"x-api-key": this.config.octoprint.accessToken,
}),
};
this.http.get(this.config.octoprint.url + "connection", httpHeaders).subscribe(
(): void => {
this.octoprintConnection = true;
this.saveConfig();
},
(error: HttpErrorResponse): void => {
this.octoprintConnection = false;
this.octoprintConnectionError = error.message;
}
);
return true;
return new Promise((resolve, reject) => {
this.http.get(this.config.octoprint.url + "connection", httpHeaders).subscribe(
(): void => {
this.octoprintConnection = true;
resolve();
},
(error: HttpErrorResponse): void => {
this.octoprintConnection = false;
this.octoprintConnectionError = error.message;
reject();
}
);
});
}

public createConfig(): boolean {
Expand All @@ -166,12 +202,12 @@ export class NoConfigComponent implements OnInit {
return true;
}

public validateConfig(): void {
public async validateConfig(): Promise<any> {
this.configValid = this.configService.validateGiven(this.config);
if (!this.configValid) {
this.configErrors = this.configService.getErrors();
} else {
this.testOctoprintAPI();
this.saveConfig();
}
}

Expand All @@ -184,16 +220,41 @@ export class NoConfigComponent implements OnInit {
this.router.navigate(["/main-screen"]);
}

public increasePage(): void {
public async increasePage(): Promise<any> {
this.page += 1;
if (this.page <= 2) {
if (JSON.stringify(this.opInstance) != JSON.stringify(this.octoprintNodes['other'])) {
this.config.octoprint.url = 'http://' + this.opInstance['url'];
this.manualEntry = false;
} else {
this.config.octoprint.url = 'http://localhost:80/api/';
this.manualEntry = true;
}
} else if (this.config.octoprint.accessToken == '' && this.page > 2) {
this.page = 2;
} else if (this.page > 2) {
if (this.octoprintConnection === false) {
await this.testOctoprintAPI().then(res => {
this.opApiMsg = '';
if (this.opInstance.name != 'other') {
this.config.printer.name = this.opInstance.name;
} else {
this.config.printer.name = '';
}
}, err => {
this.opApiMsg = 'API Error: ' + this.octoprintConnectionError;
this.page = 2;
});
}
}
if (this.page === this.totalPages) {
this.createConfig();
}
this.changeProgress();
}

public decreasePage(): void {
if (this.page === 5) {
if (this.page == this.totalPages - 1) {
this.config = this.configService.revertConfigForInput(this.config);
}
this.page -= 1;
Expand Down
4 changes: 2 additions & 2 deletions src/app/filament/filament.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export class FilamentComponent implements OnInit {
private totalPages = 5;

public page: number;
private timeout: number;
private timeout2: number;
private timeout: NodeJS.Timer;
private timeout2: NodeJS.Timer;

public filamentSpools: FilamentSpoolList;
public isLoadingSpools = true;
Expand Down
2 changes: 1 addition & 1 deletion src/app/files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { OctoprintFilesAPI, OctoprintFolderAPI, OctoprintFolderContentAPI } from
})
export class FilesService {
private httpGETRequest: Subscription;
private httpGETRequestTimeout: number;
private httpGETRequestTimeout: NodeJS.Timer;
private httpPOSTRequest: Subscription;
private httpDELETERequest: Subscription;

Expand Down
2 changes: 1 addition & 1 deletion src/app/standby/standby.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class StandbyComponent implements OnInit {
public connecting = false;
public error = "";
private connectionRetries = 3;
private displaySleepTimeout: number;
private displaySleepTimeout: NodeJS.Timer;

public constructor(
private configService: ConfigService,
Expand Down
2 changes: 1 addition & 1 deletion src/app/update/update.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class UpdateComponent implements OnInit {

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private ipc: any;
private installationAnimationInterval: number;
private installationAnimationInterval: NodeJS.Timer;
public updateProgress: UpdateDownloadProgress = {
percentage: 0,
transferred: 0,
Expand Down

0 comments on commit 8554b88

Please sign in to comment.