Skip to content
Open
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
169 changes: 87 additions & 82 deletions main/http_server/axe-os/src/app/components/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { SystemInfo as ISystemInfo, SystemStatistics as ISystemStatistics } from
import { Title } from '@angular/platform-browser';
import { AppChartComponent } from '../chart/app-chart.component';
import { SelectOption } from 'src/app/models/select-option.model';
import { eChartLabel, ChartUnitGroups, chartLabelValue, chartLabelKey } from 'src/models/enum/eChartLabel';
import { CHART_LABELS, ChartMetric, ChartUnitGroups, CHART_LABEL_TO_METRIC } from 'src/models/chart-labels';
import { LocalStorageService } from 'src/app/local-storage.service';
import { GridStack, GridItemHTMLElement } from 'gridstack';
import { DashboardEditService, WidgetDef } from 'src/app/services/dashboard-edit.service';
Expand Down Expand Up @@ -538,7 +538,7 @@ export class HomeComponent implements OnInit, OnDestroy {
const entries = labels
.filter(label => this.isSensorSupported(label, this.latestInfo))
.map((labelKey, index) => {
const label = chartLabelValue(labelKey) || labelKey;
const label = CHART_LABELS[labelKey as ChartMetric] ?? labelKey;
return {
labelKey,
label,
Expand Down Expand Up @@ -843,13 +843,12 @@ export class HomeComponent implements OnInit, OnDestroy {
.pipe(takeUntil(this.destroy$))
.subscribe({
next: stats => {
const idxHashrate = stats.labels.indexOf(chartLabelKey(eChartLabel.hashrate));
const idxPower = stats.labels.indexOf(chartLabelKey(eChartLabel.power));
const idxHashrate = stats.labels.indexOf('hashrate');
const idxPower = stats.labels.indexOf('power');
const idxTimestamp = stats.labels.indexOf('timestamp');

stats.labels.forEach((labelKey, labelIdx) => {
const valEnum = chartLabelValue(labelKey);
if (valEnum === eChartLabel.asicVoltage || valEnum === eChartLabel.voltage || valEnum === eChartLabel.current) {
if (labelKey === 'asicVoltage' || labelKey === 'voltage' || labelKey === 'current') {
stats.statistics.forEach((element: number[]) => {
if (element[labelIdx] !== undefined) {
element[labelIdx] = element[labelIdx] / 1000;
Expand Down Expand Up @@ -945,7 +944,7 @@ export class HomeComponent implements OnInit, OnDestroy {
});
}

static isSameAxisUnit(label1: eChartLabel | undefined, label2: eChartLabel | undefined) {
static isSameAxisUnit(label1: string | undefined, label2: string | undefined) {
if (!label1 || !label2) return false;
return this.getSettingsForLabel(label1).suffix == this.getSettingsForLabel(label2).suffix;
}
Expand Down Expand Up @@ -1049,7 +1048,7 @@ export class HomeComponent implements OnInit, OnDestroy {
if (!this.chartDatasets[labelKey]) {
this.chartDatasets[labelKey] = [];
}
const val = HomeComponent.getDataForLabel(chartLabelValue(labelKey) as eChartLabel, info);
const val = HomeComponent.getDataForLabel(labelKey, info);
this.chartDatasets[labelKey].push(val);
});

Expand Down Expand Up @@ -1373,9 +1372,9 @@ export class HomeComponent implements OnInit, OnDestroy {
this.lastHasFanRpm = hasFanRpm;
this.lastHasFan2Rpm = hasFan2Rpm;

this.chartDataSources = Object.entries(eChartLabel)
.filter(([key, ]) => this.isSensorSupported(key))
.map(([key, value]) => ({ name: value, value: key }));
this.chartDataSources = (Object.keys(CHART_LABELS) as ChartMetric[])
.filter(key => this.isSensorSupported(key))
.map(key => ({ name: CHART_LABELS[key], value: key }));

this.updateChartUnitGroups();
this.rebuildChartDatasets();
Expand Down Expand Up @@ -1419,8 +1418,8 @@ export class HomeComponent implements OnInit, OnDestroy {
const y1Label = y1Labels.length > 0 ? y1Labels[0] : 'none';
const y2Label = y2Labels.length > 0 ? y2Labels[0] : 'none';

this.chartOptions.scales.y.suggestedMax = this.getSuggestedMaxForLabel(chartLabelValue(y1Label) as eChartLabel, currentInfo);
this.chartOptions.scales.y2.suggestedMax = this.getSuggestedMaxForLabel(chartLabelValue(y2Label) as eChartLabel, currentInfo);
this.chartOptions.scales.y.suggestedMax = this.getSuggestedMaxForLabel(y1Label, currentInfo);
this.chartOptions.scales.y2.suggestedMax = this.getSuggestedMaxForLabel(y2Label, currentInfo);

this.lastBucket = currentBucket;
}
Expand Down Expand Up @@ -1512,88 +1511,94 @@ export class HomeComponent implements OnInit, OnDestroy {
}
}

public getSuggestedMaxForLabel(label: eChartLabel | undefined, info: ISystemInfo): number {
switch (label) {
case eChartLabel.hashrate:
case eChartLabel.hashrate_1m:
case eChartLabel.hashrate_10m:
case eChartLabel.hashrate_1h: return info.expectedHashrate;
case eChartLabel.errorPercentage: return 1;
case eChartLabel.asicTemp:
case eChartLabel.asicTemp2: return this.maxTemp;
case eChartLabel.vrTemp: return this.maxTemp + 25;
case eChartLabel.asicVoltage: return info.coreVoltage;
case eChartLabel.voltage: return info.nominalVoltage + .5;
case eChartLabel.power: return this.maxPower;
case eChartLabel.current: return this.maxPower / info.coreVoltage;
case eChartLabel.fanSpeed: return 100;
case eChartLabel.fanRpm: return 7000;
case eChartLabel.fan2Rpm: return 7000;
case eChartLabel.responseTime: return 50;
default: return 0;
public getSuggestedMaxForLabel(label: string | undefined, info: ISystemInfo): number {
if (!label) return 0;
const metric = CHART_LABEL_TO_METRIC[label] || (label as ChartMetric);
switch (metric) {
case 'hashrate':
case 'hashrate_1m':
case 'hashrate_10m':
case 'hashrate_1h': return info.expectedHashrate;
case 'errorPercentage': return 1;
case 'asicTemp':
case 'asicTemp2': return this.maxTemp;
case 'vrTemp': return this.maxTemp + 25;
case 'asicVoltage': return info.coreVoltage;
case 'voltage': return info.nominalVoltage + .5;
case 'power': return this.maxPower;
case 'current': return this.maxPower / info.coreVoltage;
case 'fanSpeed': return 100;
case 'fanRpm':
case 'fan2Rpm': return 7000;
case 'responseTime': return 50;
default: return 0;
}
}

static getDataForLabel(label: eChartLabel | undefined, info: ISystemInfo): number {
switch (label) {
case eChartLabel.hashrate: return info.hashRate;
case eChartLabel.hashrate_1m: return info.hashRate_1m;
case eChartLabel.hashrate_10m: return info.hashRate_10m;
case eChartLabel.hashrate_1h: return info.hashRate_1h;
case eChartLabel.errorPercentage: return info.errorPercentage;
case eChartLabel.asicTemp: return info.temp;
case eChartLabel.asicTemp2: return info.temp2;
case eChartLabel.vrTemp: return info.vrTemp;
case eChartLabel.asicVoltage: return info.coreVoltageActual;
case eChartLabel.voltage: return info.voltage;
case eChartLabel.power: return info.power;
case eChartLabel.current: return info.current;
case eChartLabel.fanSpeed: return info.fanspeed;
case eChartLabel.fanRpm: return info.fanrpm;
case eChartLabel.fan2Rpm: return info.fan2rpm;
case eChartLabel.wifiRssi: return info.wifiRSSI;
case eChartLabel.freeHeap: return info.freeHeap;
case eChartLabel.responseTime: return info.responseTime;
default: return 0.0;
static getDataForLabel(label: string | undefined, info: ISystemInfo): number {
if (!label) return 0.0;
const metric = CHART_LABEL_TO_METRIC[label] || (label as ChartMetric);
switch (metric) {
case 'hashrate': return info.hashRate;
case 'hashrate_1m': return info.hashRate_1m;
case 'hashrate_10m': return info.hashRate_10m;
case 'hashrate_1h': return info.hashRate_1h;
case 'errorPercentage': return info.errorPercentage;
case 'asicTemp': return info.temp;
case 'asicTemp2': return info.temp2;
case 'vrTemp': return info.vrTemp;
case 'asicVoltage': return info.coreVoltageActual;
case 'voltage': return info.voltage;
case 'power': return info.power;
case 'current': return info.current;
case 'fanSpeed': return info.fanspeed;
case 'fanRpm': return info.fanrpm;
case 'fan2Rpm': return info.fan2rpm;
case 'wifiRssi': return info.wifiRSSI;
case 'freeHeap': return info.freeHeap;
case 'responseTime': return info.responseTime;
default: return 0.0;
}
}

static getSettingsForLabel(label: eChartLabel): {suffix: string; precision: number} {
switch (label) {
case eChartLabel.hashrate:
case eChartLabel.hashrate_1m:
case eChartLabel.hashrate_10m:
case eChartLabel.hashrate_1h: return {suffix: ' H/s', precision: 0};
case eChartLabel.errorPercentage: return {suffix: ' %', precision: 2};
case eChartLabel.asicTemp:
case eChartLabel.asicTemp2:
case eChartLabel.vrTemp: return {suffix: ' °C', precision: 1};
case eChartLabel.asicVoltage:
case eChartLabel.voltage: return {suffix: ' V', precision: 1};
case eChartLabel.power: return {suffix: ' W', precision: 1};
case eChartLabel.current: return {suffix: ' A', precision: 1};
case eChartLabel.fanSpeed: return {suffix: ' %', precision: 1};
case eChartLabel.fanRpm:
case eChartLabel.fan2Rpm: return {suffix: ' rpm', precision: 0};
case eChartLabel.wifiRssi: return {suffix: ' dBm', precision: 0};
case eChartLabel.freeHeap: return {suffix: ' B', precision: 0};
case eChartLabel.responseTime: return {suffix: ' ms', precision: 1};
default: return {suffix: '', precision: 0};
static getSettingsForLabel(label: string): {suffix: string; precision: number} {
const metric = CHART_LABEL_TO_METRIC[label] || (label as ChartMetric);
switch (metric) {
case 'hashrate':
case 'hashrate_1m':
case 'hashrate_10m':
case 'hashrate_1h': return {suffix: ' H/s', precision: 0};
case 'errorPercentage': return {suffix: ' %', precision: 2};
case 'asicTemp':
case 'asicTemp2':
case 'vrTemp': return {suffix: ' °C', precision: 1};
case 'asicVoltage':
case 'voltage': return {suffix: ' V', precision: 1};
case 'power': return {suffix: ' W', precision: 1};
case 'current': return {suffix: ' A', precision: 1};
case 'fanSpeed': return {suffix: ' %', precision: 1};
case 'fanRpm':
case 'fan2Rpm': return {suffix: ' rpm', precision: 0};
case 'wifiRssi': return {suffix: ' dBm', precision: 0};
case 'freeHeap': return {suffix: ' B', precision: 0};
case 'responseTime': return {suffix: ' ms', precision: 1};
default: return {suffix: '', precision: 0};
}
}

static cbFormatValue(value: number, datasetLabel: eChartLabel, args?: any): string {
static cbFormatValue(value: number, datasetLabel: string, args?: any): string {
if (value === undefined || value === null) return '';
switch (datasetLabel) {
case eChartLabel.hashrate:
case eChartLabel.hashrate_1m:
case eChartLabel.hashrate_10m:
case eChartLabel.hashrate_1h:
const metric = CHART_LABEL_TO_METRIC[datasetLabel] || (datasetLabel as ChartMetric);
switch (metric) {
case 'hashrate':
case 'hashrate_1m':
case 'hashrate_10m':
case 'hashrate_1h':
return HashSuffixPipe.transform(value, args);
case eChartLabel.freeHeap:
case 'freeHeap':
return ByteSuffixPipe.transform(value, args);
default:
const settings = HomeComponent.getSettingsForLabel(datasetLabel);
const settings = HomeComponent.getSettingsForLabel(metric);
return value.toLocaleString(undefined, { useGrouping: false, maximumFractionDigits: args?.tickmark ? undefined : settings.precision }) + settings.suffix;
}
}
Expand Down
54 changes: 23 additions & 31 deletions main/http_server/axe-os/src/app/services/system.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { HttpClient, HttpEvent } from '@angular/common/http';
import { Injectable, Optional } from '@angular/core';
import { delay, Observable, of, timeout, from } from 'rxjs';
import { eChartLabel } from 'src/models/enum/eChartLabel';
import { chartLabelKey } from 'src/models/enum/eChartLabel';
import { chartLabelValue } from 'src/models/enum/eChartLabel';
import {
SystemInfo as ISystemInfo,
SystemStatistics as ISystemStatistics,
Expand Down Expand Up @@ -231,15 +228,15 @@ export class SystemApiService {
}

public getStatistics(y1: string[], y2: string[], uri: string = ''): Observable<ISystemStatistics> {
let columnList = [chartLabelKey(eChartLabel.hashrate), chartLabelKey(eChartLabel.power)];
let columnList = ['hashrate', 'power'];

for (const y of y1) {
if ((y != chartLabelKey(eChartLabel.hashrate)) && (y != chartLabelKey(eChartLabel.power)) && !columnList.includes(y)) {
if (y !== 'hashrate' && y !== 'power' && !columnList.includes(y)) {
columnList.push(y);
}
}
for (const y of y2) {
if ((y != chartLabelKey(eChartLabel.hashrate)) && (y != chartLabelKey(eChartLabel.power)) && !columnList.includes(y)) {
if (y !== 'hashrate' && y !== 'power' && !columnList.includes(y)) {
columnList.push(y);
}
}
Expand Down Expand Up @@ -270,31 +267,26 @@ export class SystemApiService {
for(let i: number = 0; i < 10; i++) {
statisticsList[i] = [];
for(let j: number = 0; j < columnList.length; j++) {
switch (chartLabelValue(columnList[j])) {
case eChartLabel.hashrate: statisticsList[i][j] = hashrateData[i]; break;
case eChartLabel.hashrate_1m: statisticsList[i][j] = hashrateData[i]; break;
case eChartLabel.hashrate_10m: statisticsList[i][j] = hashrateData[i]; break;
case eChartLabel.hashrate_1h: statisticsList[i][j] = hashrateData[i]; break;
case eChartLabel.power: statisticsList[i][j] = powerData[i]; break;
case eChartLabel.asicTemp: statisticsList[i][j] = asicTempData[i]; break;
case eChartLabel.asicTemp2: statisticsList[i][j] = asicTemp2Data[i]; break;
case eChartLabel.vrTemp: statisticsList[i][j] = vrTempData[i]; break;
case eChartLabel.asicVoltage: statisticsList[i][j] = asicVoltageData[i]; break;
case eChartLabel.voltage: statisticsList[i][j] = voltageData[i]; break;
case eChartLabel.current: statisticsList[i][j] = currentData[i]; break;
case eChartLabel.fanSpeed: statisticsList[i][j] = fanSpeedData[i]; break;
case eChartLabel.fanRpm: statisticsList[i][j] = fanRpmData[i]; break;
case eChartLabel.fan2Rpm: statisticsList[i][j] = fan2RpmData[i]; break;
case eChartLabel.wifiRssi: statisticsList[i][j] = wifiRssiData[i]; break;
case eChartLabel.freeHeap: statisticsList[i][j] = freeHeapData[i]; break;
case eChartLabel.responseTime: statisticsList[i][j] = responseTimeData[i]; break;
default:
if (columnList[j] === "timestamp") {
statisticsList[i][j] = timestampData[i];
} else {
statisticsList[i][j] = 0;
}
break;
switch (columnList[j]) {
case 'hashrate':
case 'hashrate_1m':
case 'hashrate_10m':
case 'hashrate_1h': statisticsList[i][j] = hashrateData[i]; break;
case 'power': statisticsList[i][j] = powerData[i]; break;
case 'asicTemp': statisticsList[i][j] = asicTempData[i]; break;
case 'asicTemp2': statisticsList[i][j] = asicTemp2Data[i]; break;
case 'vrTemp': statisticsList[i][j] = vrTempData[i]; break;
case 'asicVoltage': statisticsList[i][j] = asicVoltageData[i]; break;
case 'voltage': statisticsList[i][j] = voltageData[i]; break;
case 'current': statisticsList[i][j] = currentData[i]; break;
case 'fanSpeed': statisticsList[i][j] = fanSpeedData[i]; break;
case 'fanRpm': statisticsList[i][j] = fanRpmData[i]; break;
case 'fan2Rpm': statisticsList[i][j] = fan2RpmData[i]; break;
case 'wifiRssi': statisticsList[i][j] = wifiRssiData[i]; break;
case 'freeHeap': statisticsList[i][j] = freeHeapData[i]; break;
case 'responseTime': statisticsList[i][j] = responseTimeData[i]; break;
case 'timestamp': statisticsList[i][j] = timestampData[i]; break;
default: statisticsList[i][j] = 0; break;
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions main/http_server/axe-os/src/models/chart-labels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export const CHART_LABELS = {
hashrate: 'Hashrate',
hashrate_1m: 'Hashrate 1m',
hashrate_10m: 'Hashrate 10m',
hashrate_1h: 'Hashrate 1h',
asicTemp: 'ASIC Temp',
asicTemp2: 'ASIC Temp 2',
errorPercentage: 'Error %',
vrTemp: 'VR Temp',
asicVoltage: 'ASIC Voltage',
voltage: 'Voltage',
power: 'Power',
current: 'Current',
fanSpeed: 'Fan Speed',
fanRpm: 'Fan RPM',
fan2Rpm: 'Fan 2 RPM',
wifiRssi: 'Wi-Fi RSSI',
freeHeap: 'Free Heap',
responseTime: 'Response Time',
none: 'None',
} as const;

export type ChartMetric = keyof typeof CHART_LABELS;

export const CHART_LABEL_TO_METRIC: Record<string, ChartMetric> = Object.fromEntries(
Object.entries(CHART_LABELS).map(([k, v]) => [v, k as ChartMetric])
);

export interface ChartUnitGroup {
name: string;
value: string;
labels: ChartMetric[];
}

export const ChartUnitGroups: ChartUnitGroup[] = [
{ name: 'Hashrate (H/s)', value: 'hashrate', labels: ['hashrate', 'hashrate_1m', 'hashrate_10m', 'hashrate_1h'] },
{ name: 'Temperature (°C)', value: 'temperature', labels: ['asicTemp', 'asicTemp2', 'vrTemp'] },
{ name: 'Voltage (V)', value: 'voltage', labels: ['asicVoltage', 'voltage'] },
{ name: 'Power (W)', value: 'power', labels: ['power'] },
{ name: 'Current (A)', value: 'current', labels: ['current'] },
{ name: 'Fan Speed (RPM)', value: 'rpm', labels: ['fanRpm', 'fan2Rpm'] },
{ name: 'Percentage (%)', value: 'percentage', labels: ['fanSpeed', 'errorPercentage'] },
{ name: 'Wi-Fi RSSI (dBm)', value: 'rssi', labels: ['wifiRssi'] },
{ name: 'Free Heap (Bytes)', value: 'heap', labels: ['freeHeap'] },
{ name: 'Response Time (ms)', value: 'time', labels: ['responseTime'] },
{ name: 'None', value: 'none', labels: ['none'] }
];
Loading
Loading