mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-04-01 00:18:34 +02:00
swarm refreshing
This commit is contained in:
parent
c1d92c7f13
commit
1fae8781d4
@ -1,8 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { EditComponent } from './components/edit/edit.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { SettingsComponent } from './components/settings/settings.component';
|
||||
import { SwarmComponent } from './components/swarm/swarm.component';
|
||||
|
||||
const routes: Routes = [
|
||||
@ -11,8 +11,8 @@ const routes: Routes = [
|
||||
component: HomeComponent
|
||||
},
|
||||
{
|
||||
path: 'edit',
|
||||
component: EditComponent
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
},
|
||||
{
|
||||
path: 'swarm',
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="tab-container">
|
||||
<div class="tab" [routerLink]="['/']" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">Home
|
||||
</div>
|
||||
<div class="tab" [routerLink]="['edit']" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">
|
||||
<div class="tab" [routerLink]="['settings']" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">
|
||||
Settings
|
||||
</div>
|
||||
<div class="tab" [routerLink]="['swarm']" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">
|
||||
|
@ -48,7 +48,7 @@
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 26px;
|
||||
padding-top: 50px;
|
||||
padding-left: 5vw;
|
||||
padding-right: 5vw;
|
||||
border-left: 1px solid #304562;
|
||||
|
@ -12,24 +12,28 @@ import { EditComponent } from './components/edit/edit.component';
|
||||
import { HeaderComponent } from './components/header/header.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { LoadingComponent } from './components/loading/loading.component';
|
||||
import { SettingsComponent } from './components/settings/settings.component';
|
||||
import { SwarmComponent } from './components/swarm/swarm.component';
|
||||
import { ANSIPipe } from './pipes/ansi.pipe';
|
||||
import { DateAgoPipe } from './pipes/date-ago.pipe';
|
||||
import { SwarmComponent } from './components/swarm/swarm.component';
|
||||
|
||||
const components = [
|
||||
AppComponent,
|
||||
HeaderComponent
|
||||
HeaderComponent,
|
||||
EditComponent,
|
||||
HomeComponent,
|
||||
LoadingComponent,
|
||||
SettingsComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
...components,
|
||||
EditComponent,
|
||||
HomeComponent,
|
||||
LoadingComponent,
|
||||
|
||||
ANSIPipe,
|
||||
DateAgoPipe,
|
||||
SwarmComponent
|
||||
SwarmComponent,
|
||||
SettingsComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -1,148 +1,128 @@
|
||||
<div class="card">
|
||||
<h2>Settings</h2>
|
||||
<ng-container *ngIf="form != null">
|
||||
<form [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label>Flip Screen</label>
|
||||
<input formControlName="flipscreen" type="checkbox">
|
||||
</div>
|
||||
<!-- <div class="form-group">
|
||||
<label>Invert Screen</label>
|
||||
<input formControlName="invertscreen" type="checkbox">
|
||||
</div> -->
|
||||
<div class="form-group">
|
||||
<label>WiFi SSID: </label>
|
||||
<input formControlName="ssid" type="text">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>WiFi Password: </label>
|
||||
<input formControlName="wifiPass" type="password">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum URL: (Do not include 'stratum+tcp://' or port</label>
|
||||
<input formControlName="stratumURL" type="text">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum Port:</label>
|
||||
<input formControlName="stratumPort" type="number">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum User: </label>
|
||||
<input formControlName="stratumUser" type="text">
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="!devToolsOpen && ASICModel == eASICModel.BM1366">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Frequency </label>
|
||||
<select formControlName="frequency">
|
||||
<option value="400">400</option>
|
||||
<option value="425">425</option>
|
||||
<option value="450">450</option>
|
||||
<option value="475">475</option>
|
||||
<option value="485">485 (default)</option>
|
||||
<option value="500">500</option>
|
||||
<option value="525">525</option>
|
||||
<option value="550">550</option>
|
||||
<option value="575">575</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Core Voltage </label>
|
||||
<select formControlName="coreVoltage">
|
||||
<option value="1100">1100</option>
|
||||
<option value="1150">1150</option>
|
||||
<option value="1200">1200 (default)</option>
|
||||
<option value="1250">1250</option>
|
||||
<option value="1300">1300</option>
|
||||
</select>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!devToolsOpen && ASICModel == eASICModel.BM1397">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Frequency </label>
|
||||
<select formControlName="frequency">
|
||||
<option value="400">400</option>
|
||||
<option value="425">425 (default)</option>
|
||||
<option value="450">450</option>
|
||||
<option value="475">475</option>
|
||||
<option value="485">485</option>
|
||||
<option value="500">500</option>
|
||||
<option value="525">525</option>
|
||||
<option value="550">550</option>
|
||||
<option value="575">575</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Core Voltage </label>
|
||||
<select formControlName="coreVoltage">
|
||||
<option value="1300">1300</option>
|
||||
<option value="1350">1350</option>
|
||||
<option value="1400">1400 (default)</option>
|
||||
<option value="1450">1450</option>
|
||||
<option value="1500">1500</option>
|
||||
</select>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="devToolsOpen === true">
|
||||
<div class="form-group">
|
||||
<label>Frequency </label>
|
||||
<input formControlName="frequency" type="number">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Core Voltage</label>
|
||||
<input formControlName="coreVoltage" type="number">
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="form != null">
|
||||
<form [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label>Flip Screen</label>
|
||||
<input formControlName="flipscreen" type="checkbox">
|
||||
</div>
|
||||
<!-- <div class="form-group">
|
||||
<label>Invert Screen</label>
|
||||
<input formControlName="invertscreen" type="checkbox">
|
||||
</div> -->
|
||||
<div class="form-group">
|
||||
<label>WiFi SSID: </label>
|
||||
<input formControlName="ssid" type="text">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>WiFi Password: </label>
|
||||
<input formControlName="wifiPass" type="password">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum URL: (Do not include 'stratum+tcp://' or port</label>
|
||||
<input formControlName="stratumURL" type="text">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum Port:</label>
|
||||
<input formControlName="stratumPort" type="number">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stratum User: </label>
|
||||
<input formControlName="stratumUser" type="text">
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="!devToolsOpen && ASICModel == eASICModel.BM1366">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Invert Fan Polarity</label>
|
||||
<input formControlName="invertfanpolarity" type="checkbox">
|
||||
<label>Frequency </label>
|
||||
<select formControlName="frequency">
|
||||
<option value="400">400</option>
|
||||
<option value="425">425</option>
|
||||
<option value="450">450</option>
|
||||
<option value="475">475</option>
|
||||
<option value="485">485 (default)</option>
|
||||
<option value="500">500</option>
|
||||
<option value="525">525</option>
|
||||
<option value="550">550</option>
|
||||
<option value="575">575</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Automatic Fan Control</label>
|
||||
<input formControlName="autofanspeed" type="checkbox">
|
||||
<label>Core Voltage </label>
|
||||
<select formControlName="coreVoltage">
|
||||
<option value="1100">1100</option>
|
||||
<option value="1150">1150</option>
|
||||
<option value="1200">1200 (default)</option>
|
||||
<option value="1250">1250</option>
|
||||
<option value="1300">1300</option>
|
||||
</select>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!devToolsOpen && ASICModel == eASICModel.BM1397">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Frequency </label>
|
||||
<select formControlName="frequency">
|
||||
<option value="400">400</option>
|
||||
<option value="425">425 (default)</option>
|
||||
<option value="450">450</option>
|
||||
<option value="475">475</option>
|
||||
<option value="485">485</option>
|
||||
<option value="500">500</option>
|
||||
<option value="525">525</option>
|
||||
<option value="550">550</option>
|
||||
<option value="575">575</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group" *ngIf="form.controls['autofanspeed'].value != true">
|
||||
<label>Fan Speed {{form.controls['fanspeed'].value}}%
|
||||
<b *ngIf="form.controls['fanspeed'].value < 33" style="color:red">Danger: Could Cause
|
||||
Overheating</b> <b *ngIf="form.controls['fanspeed'].value == 100" style="color: #F2A900">S19
|
||||
Simulator</b></label>
|
||||
<input formControlName="fanspeed" type="range" [min]="0" [max]="100">
|
||||
<div class="form-group">
|
||||
<label>Core Voltage </label>
|
||||
<select formControlName="coreVoltage">
|
||||
<option value="1300">1300</option>
|
||||
<option value="1350">1350</option>
|
||||
<option value="1400">1400 (default)</option>
|
||||
<option value="1450">1450</option>
|
||||
<option value="1500">1500</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button [disabled]="form.invalid" (click)="updateSystem()" class="btn btn-primary mr-2">Save</button>
|
||||
<b style="line-height: 34px;">You must restart this device after saving for changes to take effect.</b>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="devToolsOpen === true">
|
||||
<div class="form-group">
|
||||
<label>Frequency </label>
|
||||
<input formControlName="frequency" type="number">
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</ng-container>
|
||||
<div class="form-group">
|
||||
<label>Core Voltage</label>
|
||||
<input formControlName="coreVoltage" type="number">
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Invert Fan Polarity</label>
|
||||
<input formControlName="invertfanpolarity" type="checkbox">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Automatic Fan Control</label>
|
||||
<input formControlName="autofanspeed" type="checkbox">
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Update Firmware <span *ngIf="firmwareUpdateProgress != null">{{firmwareUpdateProgress}}%</span></h2>
|
||||
<input type="file" id="file" (change)="otaUpdate($event)" accept=".bin">
|
||||
<br>
|
||||
<small>(esp-miner.bin)</small>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Update Website <span *ngIf="websiteUpdateProgress != null">{{websiteUpdateProgress}}%</span></h2>
|
||||
<input type="file" id="file" (change)="otaWWWUpdate($event)" accept=".bin">
|
||||
<br>
|
||||
<small>(www.bin)</small>
|
||||
</div>
|
||||
<div class="form-group" *ngIf="form.controls['autofanspeed'].value != true">
|
||||
<label>Fan Speed {{form.controls['fanspeed'].value}}%
|
||||
<b *ngIf="form.controls['fanspeed'].value < 33" style="color:red">Danger: Could Cause
|
||||
Overheating</b> <b *ngIf="form.controls['fanspeed'].value == 100" style="color: #F2A900">S19
|
||||
Simulator</b></label>
|
||||
<input formControlName="fanspeed" type="range" [min]="0" [max]="100">
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button [disabled]="form.invalid" (click)="updateSystem()" class="btn btn-primary mr-2">Save</button>
|
||||
<b style="line-height: 34px;">You must restart this device after saving for changes to take effect.</b>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</ng-container>
|
@ -1,4 +1,4 @@
|
||||
import { HttpErrorResponse, HttpEventType } from '@angular/common/http';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
@ -111,81 +111,4 @@ export class EditComponent {
|
||||
});
|
||||
}
|
||||
|
||||
otaUpdate(event: any) {
|
||||
const file = event.target?.files.item(0) as File;
|
||||
|
||||
if (file.name != 'esp-miner.bin') {
|
||||
this.toastrService.error('Incorrect file, looking for esp-miner.bin.', 'Error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.systemService.performOTAUpdate(file)
|
||||
.pipe(this.loadingService.lockUIUntilComplete())
|
||||
.subscribe({
|
||||
next: (event) => {
|
||||
if (event.type === HttpEventType.UploadProgress) {
|
||||
this.firmwareUpdateProgress = Math.round((event.loaded / (event.total as number)) * 100);
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (event.ok) {
|
||||
this.toastrService.success('Firmware updated', 'Success!');
|
||||
|
||||
} else {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
}
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
},
|
||||
complete: () => {
|
||||
this.firmwareUpdateProgress = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
otaWWWUpdate(event: any) {
|
||||
const file = event.target?.files.item(0) as File;
|
||||
if (file.name != 'www.bin') {
|
||||
this.toastrService.error('Incorrect file, looking for www.bin.', 'Error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.systemService.performWWWOTAUpdate(file)
|
||||
.pipe(
|
||||
this.loadingService.lockUIUntilComplete(),
|
||||
).subscribe({
|
||||
next: (event) => {
|
||||
if (event.type === HttpEventType.UploadProgress) {
|
||||
this.websiteUpdateProgress = Math.round((event.loaded / (event.total as number)) * 100);
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (event.ok) {
|
||||
setTimeout(() => {
|
||||
this.toastrService.success('Website updated', 'Success!');
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
|
||||
} else {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
}
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
},
|
||||
complete: () => {
|
||||
this.websiteUpdateProgress = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public restart() {
|
||||
this.systemService.restart().subscribe(res => {
|
||||
|
||||
});
|
||||
this.toastr.success('Success!', 'Bitaxe restarted');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
<div class="card">
|
||||
<h2>Settings</h2>
|
||||
|
||||
<app-edit></app-edit>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Update Firmware <span *ngIf="firmwareUpdateProgress != null">{{firmwareUpdateProgress}}%</span></h2>
|
||||
<input type="file" id="file" (change)="otaUpdate($event)" accept=".bin">
|
||||
<br>
|
||||
<small>(esp-miner.bin)</small>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Update Website <span *ngIf="websiteUpdateProgress != null">{{websiteUpdateProgress}}%</span></h2>
|
||||
<input type="file" id="file" (change)="otaWWWUpdate($event)" accept=".bin">
|
||||
<br>
|
||||
<small>(www.bin)</small>
|
||||
</div>
|
@ -0,0 +1,31 @@
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="password"],
|
||||
input[type="range"] {
|
||||
min-width: 250px;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
select {
|
||||
min-width: 268px;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.restart {
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (min-width:900px) {
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
input[type="range"] {
|
||||
min-width: 500px
|
||||
}
|
||||
|
||||
select {
|
||||
min-width: 518px
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SettingsComponent } from './settings.component';
|
||||
|
||||
describe('SettingsComponent', () => {
|
||||
let component: SettingsComponent;
|
||||
let fixture: ComponentFixture<SettingsComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SettingsComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(SettingsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,191 @@
|
||||
import { HttpErrorResponse, HttpEventType } from '@angular/common/http';
|
||||
import { Component } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { startWith } from 'rxjs';
|
||||
import { LoadingService } from 'src/app/services/loading.service';
|
||||
import { SystemService } from 'src/app/services/system.service';
|
||||
import { eASICModel } from 'src/models/enum/eASICModel';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrls: ['./settings.component.scss']
|
||||
})
|
||||
export class SettingsComponent {
|
||||
|
||||
public form!: FormGroup;
|
||||
|
||||
public firmwareUpdateProgress: number | null = null;
|
||||
public websiteUpdateProgress: number | null = null;
|
||||
|
||||
|
||||
public devToolsOpen: boolean = false;
|
||||
public eASICModel = eASICModel;
|
||||
public ASICModel!: eASICModel;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private systemService: SystemService,
|
||||
private toastr: ToastrService,
|
||||
private toastrService: ToastrService,
|
||||
private loadingService: LoadingService
|
||||
) {
|
||||
|
||||
window.addEventListener('resize', this.checkDevTools);
|
||||
this.checkDevTools();
|
||||
|
||||
this.systemService.getInfo()
|
||||
.pipe(this.loadingService.lockUIUntilComplete())
|
||||
.subscribe(info => {
|
||||
this.ASICModel = info.ASICModel;
|
||||
this.form = this.fb.group({
|
||||
flipscreen: [info.flipscreen == 1],
|
||||
invertscreen: [info.invertscreen == 1],
|
||||
stratumURL: [info.stratumURL, [
|
||||
Validators.required,
|
||||
Validators.pattern(/^(?!.*stratum\+tcp:\/\/).*$/),
|
||||
Validators.pattern(/^[^:]*$/),
|
||||
]],
|
||||
stratumPort: [info.stratumPort, [
|
||||
Validators.required,
|
||||
Validators.pattern(/^[^:]*$/),
|
||||
Validators.min(0),
|
||||
Validators.max(65353)
|
||||
]],
|
||||
stratumUser: [info.stratumUser, [Validators.required]],
|
||||
ssid: [info.ssid, [Validators.required]],
|
||||
wifiPass: [info.wifiPass, [Validators.required]],
|
||||
coreVoltage: [info.coreVoltage, [Validators.required]],
|
||||
frequency: [info.frequency, [Validators.required]],
|
||||
autofanspeed: [info.autofanspeed == 1, [Validators.required]],
|
||||
invertfanpolarity: [info.invertfanpolarity == 1, [Validators.required]],
|
||||
fanspeed: [info.fanspeed, [Validators.required]],
|
||||
});
|
||||
|
||||
this.form.controls['autofanspeed'].valueChanges.pipe(
|
||||
startWith(this.form.controls['autofanspeed'].value)
|
||||
).subscribe(autofanspeed => {
|
||||
if (autofanspeed) {
|
||||
this.form.controls['fanspeed'].disable();
|
||||
} else {
|
||||
this.form.controls['fanspeed'].enable();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
private checkDevTools = () => {
|
||||
if (
|
||||
window.outerWidth - window.innerWidth > 160 ||
|
||||
window.outerHeight - window.innerHeight > 160
|
||||
) {
|
||||
this.devToolsOpen = true;
|
||||
} else {
|
||||
this.devToolsOpen = false;
|
||||
}
|
||||
};
|
||||
|
||||
public updateSystem() {
|
||||
|
||||
const form = this.form.getRawValue();
|
||||
|
||||
form.frequency = parseInt(form.frequency);
|
||||
form.coreVoltage = parseInt(form.coreVoltage);
|
||||
|
||||
// bools to ints
|
||||
form.flipscreen = form.flipscreen == true ? 1 : 0;
|
||||
form.invertscreen = form.invertscreen == true ? 1 : 0;
|
||||
form.invertfanpolarity = form.invertfanpolarity == true ? 1 : 0;
|
||||
form.autofanspeed = form.autofanspeed == true ? 1 : 0;
|
||||
|
||||
this.systemService.updateSystem(form)
|
||||
.pipe(this.loadingService.lockUIUntilComplete())
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.toastr.success('Success!', 'Saved.');
|
||||
},
|
||||
error: (err: HttpErrorResponse) => {
|
||||
this.toastr.error('Error.', `Could not save. ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
otaUpdate(event: any) {
|
||||
const file = event.target?.files.item(0) as File;
|
||||
|
||||
if (file.name != 'esp-miner.bin') {
|
||||
this.toastrService.error('Incorrect file, looking for esp-miner.bin.', 'Error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.systemService.performOTAUpdate(file)
|
||||
.pipe(this.loadingService.lockUIUntilComplete())
|
||||
.subscribe({
|
||||
next: (event) => {
|
||||
if (event.type === HttpEventType.UploadProgress) {
|
||||
this.firmwareUpdateProgress = Math.round((event.loaded / (event.total as number)) * 100);
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (event.ok) {
|
||||
this.toastrService.success('Firmware updated', 'Success!');
|
||||
|
||||
} else {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
}
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
},
|
||||
complete: () => {
|
||||
this.firmwareUpdateProgress = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
otaWWWUpdate(event: any) {
|
||||
const file = event.target?.files.item(0) as File;
|
||||
if (file.name != 'www.bin') {
|
||||
this.toastrService.error('Incorrect file, looking for www.bin.', 'Error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.systemService.performWWWOTAUpdate(file)
|
||||
.pipe(
|
||||
this.loadingService.lockUIUntilComplete(),
|
||||
).subscribe({
|
||||
next: (event) => {
|
||||
if (event.type === HttpEventType.UploadProgress) {
|
||||
this.websiteUpdateProgress = Math.round((event.loaded / (event.total as number)) * 100);
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (event.ok) {
|
||||
setTimeout(() => {
|
||||
this.toastrService.success('Website updated', 'Success!');
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
|
||||
} else {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
}
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
this.toastrService.error(event.statusText, 'Error');
|
||||
},
|
||||
complete: () => {
|
||||
this.websiteUpdateProgress = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public restart() {
|
||||
this.systemService.restart().subscribe(res => {
|
||||
|
||||
});
|
||||
this.toastr.success('Success!', 'Bitaxe restarted');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -3,6 +3,9 @@
|
||||
<input formControlName="ip" type="text">
|
||||
<button style="margin-left: 15px;" class="btn btn-primary" (click)="add()">Add</button>
|
||||
</form>
|
||||
<div>
|
||||
<button class="btn btn-primary" (click)="refresh()">Refresh</button>
|
||||
</div>
|
||||
<div>
|
||||
<table cellspacing="0" cellpadding="0" *ngIf="swarm$ | async as swarm">
|
||||
<tr>
|
||||
@ -13,18 +16,22 @@
|
||||
<th>Power</th>
|
||||
<th>Temp</th>
|
||||
<th>Best Difficulty</th>
|
||||
<th>Edit</th>
|
||||
<th>Restart</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
<ng-container *ngFor="let axeOs$ of swarm">
|
||||
<tr *ngIf="axeOs$ | async as axe">
|
||||
<td>{{axe.ip}}</td>
|
||||
<td><a [href]="'http://'+axe.ip" target="_blank">{{axe.ip}}</a></td>
|
||||
<td>{{axe.hashRate | number: '1.2-2'}} <small>Gh/s</small></td>
|
||||
<td>{{axe.uptimeSeconds | dateAgo}}</td>
|
||||
<td>{{axe.sharesAccepted}}</td>
|
||||
<td>{{axe.power | number: '1.2-2'}} <small>W</small> </td>
|
||||
<td>{{axe.temp}} <small>C</small></td>
|
||||
<td>{{axe.bestDiff}}</td>
|
||||
<td><button class="btn btn-secondary" (click)="remove(axe)">X</button></td>
|
||||
<td><button class="btn btn-primary" (click)="edit(axe)">✎</button></td>
|
||||
<td><button class="btn btn-danger" (click)="restart(axe)">♺</button></td>
|
||||
<td><button class="btn btn-secondary" (click)="remove(axe)">✖</button></td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
</table>
|
||||
|
@ -19,4 +19,8 @@ th,
|
||||
td {
|
||||
padding: 1rem 1rem;
|
||||
border-bottom: 1px solid #304562;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { catchError, map, Observable, of, startWith, switchMap } from 'rxjs';
|
||||
import { BehaviorSubject, catchError, map, Observable, of, startWith, switchMap } from 'rxjs';
|
||||
import { SystemService } from 'src/app/services/system.service';
|
||||
|
||||
@Component({
|
||||
@ -15,6 +15,8 @@ export class SwarmComponent {
|
||||
|
||||
public swarm$: Observable<Observable<any>[]>;
|
||||
|
||||
public refresh$: BehaviorSubject<null> = new BehaviorSubject(null);
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private systemService: SystemService,
|
||||
@ -28,7 +30,11 @@ export class SwarmComponent {
|
||||
map(swarmInfo => {
|
||||
return swarmInfo.map(({ ip }) => {
|
||||
// Make individual API calls for each IP
|
||||
return this.systemService.getInfo(`http://${ip}`).pipe(
|
||||
return this.refresh$.pipe(
|
||||
switchMap(() => {
|
||||
return this.systemService.getInfo(`http://${ip}`);
|
||||
})
|
||||
).pipe(
|
||||
startWith({ ip }),
|
||||
map(info => {
|
||||
return {
|
||||
@ -70,6 +76,20 @@ export class SwarmComponent {
|
||||
|
||||
}
|
||||
|
||||
public refresh() {
|
||||
this.refresh$.next(null);
|
||||
}
|
||||
|
||||
public edit(axe: any) {
|
||||
|
||||
}
|
||||
public restart(axe: any) {
|
||||
this.systemService.restart(`http://${axe.ip}`).subscribe(res => {
|
||||
|
||||
});
|
||||
this.toastr.success('Success!', 'Bitaxe restarted');
|
||||
}
|
||||
|
||||
public remove(axe: any) {
|
||||
this.systemService.getSwarmInfo().pipe(
|
||||
switchMap((swarm: any) => {
|
||||
|
@ -15,9 +15,9 @@ export class SystemService {
|
||||
private httpClient: HttpClient
|
||||
) { }
|
||||
|
||||
public getInfo(ip: string = ''): Observable<ISystemInfo> {
|
||||
public getInfo(uri: string = ''): Observable<ISystemInfo> {
|
||||
if (environment.production) {
|
||||
return this.httpClient.get(`${ip}/api/system/info`) as Observable<ISystemInfo>;
|
||||
return this.httpClient.get(`${uri}/api/system/info`) as Observable<ISystemInfo>;
|
||||
} else {
|
||||
return of(
|
||||
{
|
||||
@ -53,8 +53,8 @@ export class SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
public restart() {
|
||||
return this.httpClient.post(`/api/system/restart`, {});
|
||||
public restart(uri: string = '') {
|
||||
return this.httpClient.post(`${uri}/api/system/restart`, {});
|
||||
}
|
||||
|
||||
public updateSystem(update: any) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user