Skip to content

Commit cf7ed29

Browse files
committed
feat: add max miners mode config
1 parent 2176678 commit cf7ed29

5 files changed

Lines changed: 37 additions & 3 deletions

File tree

‎scheduler/config.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Config struct {
4343
FanRHighThreshold int `json:"fanr_high_threshold"` // FanR threshold to decrease work mode
4444
FanRLowThreshold int `json:"fanr_low_threshold"` // FanR threshold to increase work mode
4545
MinerWorkModeUpgradeChecks int `json:"miner_work_mode_upgrade_checks"` // Number of consecutive checks at current work mode required before upgrading
46+
MinerMaxWorkMode int `json:"miner_max_work_mode"` // Maximum work mode miners may be upgraded to (0=Eco, 1=Standard, 2=Super)
4647

4748
// Power consumption settings (in kilowatts)
4849
MinersPowerLimit float64 `json:"miners_power_limit"` // Maximum total power limit for miners in kW
@@ -137,6 +138,7 @@ func DefaultConfig() *Config {
137138
ImportPriceDeliveryFee: 40.0, // 40 EUR/MWh for delivery
138139
ExportPriceOperatorFee: 17.0, // 17 EUR/MWh from Operator
139140
MinerWorkModeUpgradeChecks: 5, // 5 consecutive checks required before upgrading work mode
141+
MinerMaxWorkMode: 1, // Standard mode (1) is the default maximum
140142
MinersPowerLimit: 30.0, // 30 kW total power limit for miners
141143
MinerPowerStandby: 0.05, // 0.05 kW (50 W) in standby
142144
MinerPowerEco: 0.8, // 0.8 kW (800 W) in eco mode
@@ -242,6 +244,10 @@ func (c *Config) Validate() error {
242244
return fmt.Errorf("miner_work_mode_upgrade_checks must be greater than 0, got: %d", c.MinerWorkModeUpgradeChecks)
243245
}
244246

247+
if c.MinerMaxWorkMode < 0 || c.MinerMaxWorkMode > 2 {
248+
return fmt.Errorf("miner_max_work_mode must be 0 (Eco), 1 (Standard), or 2 (Super), got: %d", c.MinerMaxWorkMode)
249+
}
250+
245251
if c.APITimeout <= 0 {
246252
return fmt.Errorf("api_timeout must be greater than 0, got: %s", c.APITimeout)
247253
}

‎scheduler/miners.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ func (s *MinerScheduler) controlMiner(m *miners.AvalonQHost, totalPower float64,
311311
} else if fanR < s.config.FanRLowThreshold && totalPower <= effectiveLimit {
312312
// Increase work mode only if the last N consecutive checks all passed at the current work mode
313313
requiredChecks := s.config.MinerWorkModeUpgradeChecks
314-
if len(m.LiteStatsHistory) < requiredChecks || currentWorkMode == miners.AvalonSuperMode {
314+
if len(m.LiteStatsHistory) < requiredChecks || currentWorkMode >= miners.AvalonWorkMode(s.config.MinerMaxWorkMode) {
315315
return currentState, currentWorkMode
316316
}
317317
recentHistory := m.LiteStatsHistory[len(m.LiteStatsHistory)-requiredChecks:]

‎scheduler/miners_test.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func newTestScheduler(cfg *Config) *MinerScheduler {
3838
MinerPowerSuper: 2.0,
3939
MinersPowerLimit: 10.0,
4040
MinerWorkModeUpgradeChecks: 5,
41+
MinerMaxWorkMode: 2,
4142
}
4243
}
4344
return NewMinerScheduler(cfg, log.New(os.Stdout, "TEST: ", log.LstdFlags))
@@ -413,6 +414,7 @@ func TestControlMiner_CustomThresholds(t *testing.T) {
413414
MinerPowerSuper: 2.0,
414415
MinersPowerLimit: 10.0,
415416
MinerWorkModeUpgradeChecks: 5,
417+
MinerMaxWorkMode: 2,
416418
}
417419
scheduler := newTestScheduler(cfg)
418420

@@ -625,6 +627,7 @@ func TestControlMiner_PowerCalculation(t *testing.T) {
625627
MinerPowerSuper: 2.5,
626628
MinersPowerLimit: 10.0,
627629
MinerWorkModeUpgradeChecks: 5,
630+
MinerMaxWorkMode: 2,
628631
}
629632
scheduler := newTestScheduler(cfg)
630633

‎web/src/components/ConfigMenu.tsx‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ interface ConfigMenuProps {
77
onClose: () => void;
88
}
99

10-
type FieldType = "text" | "number" | "boolean" | "select" | "duration";
10+
type FieldType = "text" | "number" | "boolean" | "select" | "duration" | "numericSelect";
1111

1212
interface FieldDef {
1313
key: keyof EmsConfig;
@@ -19,6 +19,7 @@ interface FieldDef {
1919
max?: number;
2020
step?: number;
2121
options?: string[];
22+
numericOptions?: { value: number; label: string }[];
2223
sensitive?: boolean;
2324
}
2425

@@ -172,6 +173,17 @@ const SECTIONS: Section[] = [
172173
min: 1,
173174
hint: "Consecutive checks at current work mode required before upgrading",
174175
},
176+
{
177+
key: "miner_max_work_mode",
178+
label: "Max Work Mode",
179+
type: "numericSelect",
180+
numericOptions: [
181+
{ value: 0, label: "Eco" },
182+
{ value: 1, label: "Standard" },
183+
{ value: 2, label: "Super" },
184+
],
185+
hint: "Highest work mode miners are allowed to reach",
186+
},
175187
{
176188
key: "miners_power_limit",
177189
label: "Total Power Limit",
@@ -511,7 +523,7 @@ function ConfigField({ def, value, onChange }: FieldProps) {
511523
onChange(def.key, raw as boolean);
512524
return;
513525
}
514-
if (def.type === "number") {
526+
if (def.type === "number" || def.type === "numericSelect") {
515527
const parsed = raw === "" ? 0 : Number(raw);
516528
onChange(def.key, isNaN(parsed) ? 0 : parsed);
517529
return;
@@ -554,6 +566,18 @@ function ConfigField({ def, value, onChange }: FieldProps) {
554566
</option>
555567
))}
556568
</select>
569+
) : def.type === "numericSelect" ? (
570+
<select
571+
className="config-input"
572+
value={String(value ?? 0)}
573+
onChange={(e) => handleChange(e.target.value)}
574+
>
575+
{def.numericOptions?.map((opt) => (
576+
<option key={opt.value} value={String(opt.value)}>
577+
{opt.label}
578+
</option>
579+
))}
580+
</select>
557581
) : def.type === "number" ? (
558582
<input
559583
type="number"

‎web/src/types/api.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface EmsConfig {
1717
fanr_high_threshold: number;
1818
fanr_low_threshold: number;
1919
miner_work_mode_upgrade_checks: number;
20+
miner_max_work_mode: number;
2021
miners_power_limit: number;
2122
miner_power_standby: number;
2223
miner_power_eco: number;

0 commit comments

Comments
 (0)