Add network fee support to dashboard configuration

Updated the `reset_chart_data` function to include a new `network_fee` parameter in the `MiningDashboardService`. Modified `config.json` to add a default `network_fee` key. Enhanced `load_config` in `config.py` to handle the new parameter. Updated the `MiningDashboardService` constructor and `fetch_metrics` method to utilize the `network_fee` in calculations. Added a new input field for `network_fee` in `boot.html` and updated related JavaScript functions to manage this input. Improved the "Use Defaults" button functionality to reset the `network_fee` to its default value.
This commit is contained in:
DJObleezy 2025-04-22 07:43:57 -07:00
parent b8321fe3b0
commit bdb9552576
5 changed files with 79 additions and 47 deletions

5
App.py
View File

@ -850,12 +850,13 @@ app.wsgi_app = RobustMiddleware(app.wsgi_app)
# Update this section in App.py to properly initialize services
# Initialize the dashboard service and worker service
# Initialize the dashboard service with network fee parameter
config = load_config()
dashboard_service = MiningDashboardService(
config.get("power_cost", 0.0),
config.get("power_usage", 0.0),
config.get("wallet")
config.get("wallet"),
network_fee=config.get("network_fee", 0.0) # Add network fee parameter
)
worker_service = WorkerService()
# Connect the services

View File

@ -1,6 +1,7 @@
{
"power_cost": 0.0,
"power_usage": 0.0,
"wallet": "yourwallethere"
"timezone": "America/Los_Angeles" // Add the timezone key
"power_cost": 0.0,
"power_usage": 0.0,
"wallet": "yourwallethere",
"timezone": "America/Los_Angeles",
"network_fee": 0.0
}

View File

@ -12,15 +12,13 @@ CONFIG_FILE = "config.json"
def load_config():
"""
Load configuration from file or return defaults if file doesn't exist.
Returns:
dict: Configuration dictionary with settings
"""
default_config = {
"power_cost": 0.0,
"power_usage": 0.0,
"wallet": "yourwallethere",
"timezone": "America/Los_Angeles" # Add default timezone
"timezone": "America/Los_Angeles",
"network_fee": 0.0 # Add default network fee
}
if os.path.exists(CONFIG_FILE):
@ -28,6 +26,12 @@ def load_config():
with open(CONFIG_FILE, "r") as f:
config = json.load(f)
logging.info(f"Configuration loaded from {CONFIG_FILE}")
# Ensure network_fee is present even in existing config files
if "network_fee" not in config:
config["network_fee"] = default_config["network_fee"]
logging.info("Added missing network_fee to config with default value")
return config
except Exception as e:
logging.error(f"Error loading config: {e}")

View File

@ -17,18 +17,20 @@ from config import get_timezone
class MiningDashboardService:
"""Service for fetching and processing mining dashboard data."""
def __init__(self, power_cost, power_usage, wallet):
def __init__(self, power_cost, power_usage, wallet, network_fee=0.0):
"""
Initialize the mining dashboard service.
Args:
power_cost (float): Cost of power in $ per kWh
power_usage (float): Power usage in watts
wallet (str): Bitcoin wallet address for Ocean.xyz
network_fee (float): Additional network fee percentage
"""
self.power_cost = power_cost
self.power_usage = power_usage
self.wallet = wallet
self.network_fee = network_fee
self.cache = {}
self.sats_per_btc = 100_000_000
self.previous_values = {}
@ -37,13 +39,13 @@ class MiningDashboardService:
def fetch_metrics(self):
"""
Fetch metrics from Ocean.xyz and other sources.
Returns:
dict: Mining metrics data
"""
# Add execution time tracking
start_time = time.time()
try:
with ThreadPoolExecutor(max_workers=2) as executor:
future_ocean = executor.submit(self.get_ocean_data)
@ -60,12 +62,12 @@ class MiningDashboardService:
return None
difficulty, network_hashrate, btc_price, block_count = btc_stats
# If we failed to get network hashrate, use a reasonable default to prevent division by zero
if network_hashrate is None:
logging.warning("Using default network hashrate")
network_hashrate = 500e18 # ~500 EH/s as a reasonable fallback
# If we failed to get BTC price, use a reasonable default
if btc_price is None:
logging.warning("Using default BTC price")
@ -80,7 +82,25 @@ class MiningDashboardService:
block_reward = 3.125
blocks_per_day = 86400 / 600
daily_btc_gross = hash_proportion * block_reward * blocks_per_day
daily_btc_net = daily_btc_gross * (1 - 0.02 - 0.028)
# Use actual pool fees instead of hardcoded values
# Get the pool fee percentage from ocean_data, default to 2.0% if not available
pool_fee_percent = ocean_data.pool_fees_percentage if ocean_data.pool_fees_percentage is not None else 2.0
# Get the network fee from the configuration (default to 0.0% if not set)
from config import load_config
config = load_config()
network_fee_percent = config.get("network_fee", 0.0)
# Calculate total fee percentage (converting from percentage to decimal)
total_fee_rate = (pool_fee_percent + network_fee_percent) / 100.0
# Calculate net BTC accounting for actual fees
daily_btc_net = daily_btc_gross * (1 - total_fee_rate)
# Log the fee calculations for transparency
logging.info(f"Earnings calculation using pool fee: {pool_fee_percent}% + network fee: {network_fee_percent}%")
logging.info(f"Total fee rate: {total_fee_rate}, Daily BTC gross: {daily_btc_gross}, Daily BTC net: {daily_btc_net}")
daily_revenue = round(daily_btc_net * btc_price, 2) if btc_price is not None else None
daily_power_cost = round((self.power_usage / 1000) * self.power_cost * 24, 2)
@ -113,7 +133,11 @@ class MiningDashboardService:
'block_number': block_count,
'network_hashrate': (network_hashrate / 1e18) if network_hashrate else None,
'difficulty': difficulty,
'daily_btc_gross': daily_btc_gross,
'daily_btc_net': daily_btc_net,
'pool_fee_percent': pool_fee_percent,
'network_fee_percent': network_fee_percent,
'total_fee_rate': total_fee_rate,
'estimated_earnings_per_day': estimated_earnings_per_day,
'daily_revenue': daily_revenue,
'daily_power_cost': daily_power_cost,

View File

@ -280,7 +280,16 @@
</label>
<input type="number" id="power-usage" step="50" min="0" placeholder="13450" value="">
</div>
<div id="form-message"></div>
<div class="form-group">
<label for="network-fee">
Network Fee (%)
<span class="tooltip">
?
<span class="tooltip-text">Additional fees beyond pool fee, like Firmware fees</span>
</span>
</label>
<input type="number" id="network-fee" step="0.1" min="0" max="10" placeholder="0.0" value="">
</div>
<div class="form-group">
<label for="timezone">
Timezone
@ -305,6 +314,7 @@
</optgroup>
</select>
</div>
<div id="form-message"></div>
<div class="form-actions">
<button class="btn btn-secondary" id="use-defaults">Use Defaults</button>
<button class="btn" id="save-config">Save & Continue</button>
@ -383,18 +393,20 @@
loadTimezoneFromConfig();
});
// Update the saveConfig function to include timezone
// Update saveConfig to include network fee
function saveConfig() {
const wallet = document.getElementById('wallet-address').value.trim();
const powerCost = parseFloat(document.getElementById('power-cost').value) || 0;
const powerUsage = parseFloat(document.getElementById('power-usage').value) || 0;
const timezone = document.getElementById('timezone').value;
const networkFee = parseFloat(document.getElementById('network-fee').value) || 0;
const updatedConfig = {
wallet: wallet || currentConfig.wallet,
wallet: wallet || (currentConfig ? currentConfig.wallet : ""),
power_cost: powerCost,
power_usage: powerUsage,
timezone: timezone
timezone: timezone,
network_fee: networkFee
};
return fetch('/api/config', {
@ -445,12 +457,10 @@
power_usage: 0.0
};
// Replace the current loadConfig function with this improved version
// Update loadConfig function to include network fee
function loadConfig() {
// Return a promise that resolves when the config is loaded
return new Promise((resolve, reject) => {
// Always make a fresh request to get the latest config
fetch('/api/config?nocache=' + new Date().getTime()) // Add cache-busting parameter
fetch('/api/config?nocache=' + new Date().getTime())
.then(response => {
if (!response.ok) {
throw new Error('Failed to load configuration: ' + response.statusText);
@ -461,12 +471,13 @@
console.log("Loaded configuration:", data);
currentConfig = data;
// After loading, always update the form fields with the latest values
// Update form fields with latest values
document.getElementById('wallet-address').value = currentConfig.wallet || "";
document.getElementById('power-cost').value = currentConfig.power_cost || "";
document.getElementById('power-usage').value = currentConfig.power_usage || "";
document.getElementById('network-fee').value = currentConfig.network_fee || "";
configLoaded = true;
resolve(currentConfig); // Resolve the promise with the config data
resolve(currentConfig);
})
.catch(err => {
console.error("Error loading config:", err);
@ -474,14 +485,15 @@
currentConfig = {
wallet: "yourwallethere",
power_cost: 0.0,
power_usage: 0.0
power_usage: 0.0,
network_fee: 0.0
};
// Still update the form with default values
document.getElementById('wallet-address').value = currentConfig.wallet || "";
document.getElementById('power-cost').value = currentConfig.power_cost || "";
document.getElementById('power-usage').value = currentConfig.power_usage || "";
resolve(currentConfig); // Resolve the promise with the default config
document.getElementById('network-fee').value = currentConfig.network_fee || "";
resolve(currentConfig);
});
});
}
@ -567,29 +579,19 @@
});
});
// Replace the current Use Defaults button event listener with this fixed version
// Update Use Defaults button handler
document.getElementById('use-defaults').addEventListener('click', function () {
console.log("Use Defaults button clicked");
// Set default values including network fee
document.getElementById('wallet-address').value = "bc1py5zmrtssheq3shd8cptpl5l5m3txxr5afynyg2gyvam6w78s4dlqqnt4v9";
document.getElementById('power-cost').value = 0.0;
document.getElementById('power-usage').value = 0.0;
document.getElementById('network-fee').value = 0.0;
// Always use the hardcoded default values, not the currentConfig
const defaultWallet = "bc1py5zmrtssheq3shd8cptpl5l5m3txxr5afynyg2gyvam6w78s4dlqqnt4v9";
const defaultPowerCost = 0.0;
const defaultPowerUsage = 0.0;
console.log("Setting to default values");
// Apply the hardcoded default values to the form fields
document.getElementById('wallet-address').value = defaultWallet;
document.getElementById('power-cost').value = defaultPowerCost;
document.getElementById('power-usage').value = defaultPowerUsage;
// Show visual feedback that the button was clicked
// Visual feedback
const btn = document.getElementById('use-defaults');
const originalText = btn.textContent;
btn.textContent = "Defaults Applied";
btn.style.backgroundColor = "#32CD32";
// Reset the button after a short delay
setTimeout(function () {
btn.textContent = originalText;
btn.style.backgroundColor = "";