Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for TPLinkSmartPlug plugin #1256

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ export class AppComponent implements OnInit {
}

private checkInvalidConfig() {
if (_.isEqual(this.configService.getErrors(), this.service.getUpdateError())) {
if (this.service.autoFixError()) {
const errors = this.configService.getErrors();

if (this.service.hasUpdateError(errors)) {
if (this.service.fixUpdateErrors(errors)) {
this.initialize();
} else {
this.configService.setUpdate();
Expand Down
42 changes: 30 additions & 12 deletions src/app/app.service.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import _ from 'lodash';
import { ElectronService } from 'ngx-electron';

import { Config } from './config/config.model';
import { ConfigService } from './config/config.service';
import { NotificationService } from './notification/notification.service';

@Injectable({
providedIn: 'root',
})
export class AppService {
private updateError: string[];
private updateError: Record<string, (config: Config) => void>;
private loadedFile = false;
public version: string;
public latestVersion: string;
Expand All @@ -25,19 +27,35 @@ export class AppService {
this.enableVersionListener();
this.enableCustomCSSListener();
this.electronService.ipcRenderer.send('appInfo');
this.updateError = [
".printer should have required property 'zBabystepGCode'",
".octodash should have required property 'previewProgressCircle'",
];

// list of all error following an upgrade
this.updateError = {
".printer should have required property 'zBabystepGCode'": config => (config.printer.zBabystepGCode = 'M290 Z'),
".plugins should have required property 'tpLinkSmartPlug'": config =>
(config.plugins.tpLinkSmartPlug = { enabled: true, smartPlugIP: '127.0.0.1' }),
".octodash should have required property 'previewProgressCircle'": config =>
(config.octodash.previewProgressCircle = false),
".octodash should have required property 'turnOnPrinterWhenExitingSleep'": config => {
config.octodash.turnOnPrinterWhenExitingSleep = config.plugins.psuControl.turnOnPSUWhenExitingSleep ?? false;
delete config.plugins.psuControl.turnOnPSUWhenExitingSleep;
},
};
}

// If the errors can be automatically fixed return true here
public autoFixError(): boolean {
// If all errors can be automatically fixed return true here
public fixUpdateErrors(errors: string[]): boolean {
const config = this.configService.getCurrentConfig();
config.printer.zBabystepGCode = 'M290 Z';
config.octodash.previewProgressCircle = false;

let fullyAutofixed = true;
for (const error of errors) {
if (_.hasIn(this.updateError, error)) {
this.updateError[error](config);
} else {
fullyAutofixed = false;
}
}
this.configService.saveConfig(config);
return true;
return fullyAutofixed;
}

private enableVersionListener(): void {
Expand Down Expand Up @@ -89,8 +107,8 @@ export class AppService {
this.electronService.ipcRenderer.send('screenWakeup');
}

public getUpdateError(): string[] {
return this.updateError;
public hasUpdateError(errors: string[]): boolean {
return _.intersection(errors, _.keys(this.updateError)).length > 0;
xunleii marked this conversation as resolved.
Show resolved Hide resolved
}

public setLoadedFile(value: boolean): void {
Expand Down
5 changes: 5 additions & 0 deletions src/app/config/config.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export const defaultConfig: Config = {
enabled: false,
turnOnPSUWhenExitingSleep: false,
},
tpLinkSmartPlug: {
enabled: false,
smartPlugIP: '127.0.0.1',
},
},
octodash: {
customActions: [
Expand Down Expand Up @@ -101,6 +105,7 @@ export const defaultConfig: Config = {
pollingInterval: 2000,
touchscreen: true,
turnScreenOffWhileSleeping: false,
turnOnPrinterWhenExitingSleep: false,
preferPreviewWhilePrinting: false,
previewProgressCircle: false,
},
Expand Down
10 changes: 9 additions & 1 deletion src/app/config/config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ interface Plugins {
preheatButton: Plugin;
printTimeGenius: Plugin;
psuControl: PSUControlPlugin;
tpLinkSmartPlug: TPLinkSmartPlugPlugin;
}

interface Plugin {
Expand All @@ -67,7 +68,13 @@ interface EnclosurePlugin extends Plugin {
}

interface PSUControlPlugin extends Plugin {
turnOnPSUWhenExitingSleep: boolean;
// TODO: this option still exists to allow migration path... need to be removed
// when the new `turnOnPSUWhenExitingSleep` will be released
turnOnPSUWhenExitingSleep?: boolean;
}

interface TPLinkSmartPlugPlugin extends Plugin {
smartPlugIP: string;
}

interface OctoDash {
Expand All @@ -76,6 +83,7 @@ interface OctoDash {
pollingInterval: number;
touchscreen: boolean;
turnScreenOffWhileSleeping: boolean;
turnOnPrinterWhenExitingSleep: boolean;
preferPreviewWhilePrinting: boolean;
previewProgressCircle: boolean;
}
Expand Down
23 changes: 20 additions & 3 deletions src/app/config/config.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export const configSchema = {
'preheatButton',
'printTimeGenius',
'psuControl',
'tpLinkSmartPlug',
],
properties: {
displayLayerProgress: {
Expand Down Expand Up @@ -186,16 +187,27 @@ export const configSchema = {
psuControl: {
$id: '#/properties/plugins/properties/psuControl',
type: 'object',
required: ['enabled', 'turnOnPSUWhenExitingSleep'],
required: ['enabled'],
properties: {
enabled: {
$id: '#/properties/plugins/properties/printTimeGenius/properties/enabled',
type: 'boolean',
},
turnOnPSUWhenExitingSleep: {
$id: '#/properties/plugins/properties/turnOnPSUWhenExitingSleep',
},
},
tpLinkSmartPlug: {
$id: '#/properties/plugins/properties/tpLinkSmartPlug',
type: 'object',
required: ['enabled', 'smartPlugIP'],
properties: {
enabled: {
$id: '#/properties/plugins/properties/tpLinkSmartPlug/properties/enabled',
type: 'boolean',
},
smartPlugIP: {
$id: '#/properties/plugins/properties/tpLinkSmartPlug/properties/smartPlugIP',
type: 'string',
},
},
},
},
Expand All @@ -209,6 +221,7 @@ export const configSchema = {
'pollingInterval',
'touchscreen',
'turnScreenOffWhileSleeping',
'turnOnPrinterWhenExitingSleep',
'preferPreviewWhilePrinting',
'previewProgressCircle',
],
Expand Down Expand Up @@ -276,6 +289,10 @@ export const configSchema = {
$id: '#/properties/octodash/properties/turnScreenOffWhileSleeping',
type: 'boolean',
},
turnOnPrinterWhenExitingSleep: {
$id: '#/properties/octodash/properties/turnOnPrinterWhenExitingSleep',
type: 'boolean',
},
preferPreviewWhilePrinting: {
$id: '#/properties/octodash/properties/preferPreviewWhilePrinting',
type: 'boolean',
Expand Down
14 changes: 11 additions & 3 deletions src/app/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class ConfigService {

public getErrors(): string[] {
const errors = [];
this.validator.errors.forEach((error): void => {
this.validator.errors?.forEach((error): void => {
if (error.keyword === 'type') {
errors.push(`${error.dataPath} ${error.message}`);
} else {
Expand All @@ -97,6 +97,7 @@ export class ConfigService {
const configStored = this.store.get('config');
if (this.validateGiven(configStored)) {
this.config = config;
this.valid = true;
this.generateHttpHeaders();
return null;
} else {
Expand Down Expand Up @@ -193,10 +194,17 @@ export class ConfigService {
return this.config.octodash.turnScreenOffWhileSleeping;
}

public turnOnPSUWhenExitingSleep(): boolean {
return this.config.plugins.psuControl.turnOnPSUWhenExitingSleep;
public getAutomaticPrinterPowerOn(): boolean {
return this.config.octodash.turnOnPrinterWhenExitingSleep;
}

public useTpLinkSmartPlug(): boolean {
return this.config.plugins.tpLinkSmartPlug.enabled;
}

public getSmartPlugIP(): string {
return this.config.plugins.tpLinkSmartPlug.smartPlugIP;
}
public getFilamentThickness(): number {
return this.config.filament.thickness;
}
Expand Down
8 changes: 7 additions & 1 deletion src/app/config/setup/plugins/plugins.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,11 @@
</span>
PSU Control
</div>
<div class="setup__explanation">Enclosure and PSU Control Plugin can be configured further in the settings.</div>
<div class="setup__checkbox-container" (click)="changeTPLinkSmartPlugPlugin()">
<span class="setup__checkbox">
<span class="setup__checkbox-checked" *ngIf="tplinkSmartPlugPlugin"></span>
</span>
TPLink-SmartPlug
</div>
<div class="setup__explanation">Enclosure, PSU Control and TPLink-SmartPlug plugins can be configured further in the settings.</div>
</div>
7 changes: 7 additions & 0 deletions src/app/config/setup/plugins/plugins.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ export class PluginsComponent {
@Input() preheatButtonPlugin: boolean;
@Input() printTimeGeniusPlugin: boolean;
@Input() psuControlPlugin: boolean;
@Input() tplinkSmartPlugPlugin: boolean;

@Output() displayLayerProgressPluginChange = new EventEmitter<boolean>();
@Output() enclosurePluginChange = new EventEmitter<boolean>();
@Output() filamentManagerPluginChange = new EventEmitter<boolean>();
@Output() preheatButtonPluginChange = new EventEmitter<boolean>();
@Output() printTimeGeniusPluginChange = new EventEmitter<boolean>();
@Output() psuControlPluginChange = new EventEmitter<boolean>();
@Output() tplinkSmartPlugPluginChange = new EventEmitter<boolean>();

public changeDisplayLayerProgressPlugin(): void {
this.displayLayerProgressPlugin = !this.displayLayerProgressPlugin;
Expand Down Expand Up @@ -49,4 +51,9 @@ export class PluginsComponent {
this.psuControlPlugin = !this.psuControlPlugin;
this.psuControlPluginChange.emit(this.psuControlPlugin);
}

public changeTPLinkSmartPlugPlugin(): void {
this.tplinkSmartPlugPlugin = !this.tplinkSmartPlugPlugin;
this.tplinkSmartPlugPluginChange.emit(this.tplinkSmartPlugPlugin);
}
}
1 change: 1 addition & 0 deletions src/app/config/setup/setup.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
[(preheatButtonPlugin)]="config.plugins.preheatButton.enabled"
[(printTimeGeniusPlugin)]="config.plugins.printTimeGenius.enabled"
[(psuControlPlugin)]="config.plugins.psuControl.enabled"
[(tplinkSmartPlugPlugin)]="config.plugins.tplinkSmartPlug.enabled"
></app-config-setup-plugins>

<div *ngIf="page === 6">
Expand Down
8 changes: 8 additions & 0 deletions src/app/control/control.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { OctoprintService } from '../octoprint.service';
import { OctoprintPrinterProfile } from '../octoprint/model/printerProfile';
import { EnclosureService } from '../plugin-service/enclosure.service';
import { PsuControlService } from '../plugin-service/psu-control.service';
import { TPLinkSmartPlugService } from '../plugin-service/tplink-smartplug.service';
import { PrinterService } from '../printer.service';
import { PrinterProfileService } from '../printerprofile.service';

Expand All @@ -31,6 +32,7 @@ export class ControlComponent {
private configService: ConfigService,
private psuControlService: PsuControlService,
private enclosureService: EnclosureService,
private tplinkSmartPlugService: TPLinkSmartPlugService,
private router: Router,
) {
this.printerProfile = {
Expand Down Expand Up @@ -121,6 +123,12 @@ export class ControlComponent {
case '[!POWERTOGGLE]':
this.psuControlService.togglePSU();
break;
case '[!TPLINKOFF]':
this.tplinkSmartPlugService.changePowerState(false);
break;
case '[!TPLINKON]':
this.tplinkSmartPlugService.changePowerState(true);
break;
default: {
if (command.includes('[!WEB]')) {
this.openIFrame(command.replace('[!WEB]', ''));
Expand Down
38 changes: 38 additions & 0 deletions src/app/plugin-service/tplink-smartplug.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Subscription } from 'rxjs';

import { ConfigService } from '../config/config.service';
import { NotificationService } from '../notification/notification.service';

@Injectable({
providedIn: 'root',
})
export class TPLinkSmartPlugService {
private httpPOSTRequest: Subscription;

public constructor(
private configService: ConfigService,
private notificationService: NotificationService,
private http: HttpClient,
) {}

public changePowerState(on: boolean): void {
if (this.httpPOSTRequest) {
this.httpPOSTRequest.unsubscribe();
}

const payload = {
command: on ? 'turnOn' : 'turnOff',
ip: this.configService.getSmartPlugIP(),
};
this.httpPOSTRequest = this.http
.post(this.configService.getURL('plugin/tplinksmartplug'), payload, this.configService.getHTTPHeaders())
.subscribe(
(): void => null,
(error: HttpErrorResponse): void => {
this.notificationService.setError("Can't control TPLink SmartPlug!", error.message);
},
);
}
}
Loading