CalejoControl/tests/mock_services/mock_optimizer_server.py

280 lines
9.6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
Mock Optimizer Server for testing
Simulates optimization service for industrial processes
"""
import json
import random
import time
from datetime import datetime, timedelta
from flask import Flask, jsonify, request
app = Flask(__name__)
# Mock optimization models
optimization_models = {
"energy_optimization": {
"name": "Energy Consumption Optimizer",
"description": "Optimizes energy usage while maintaining production targets",
"parameters": ["power_load", "time_of_day", "production_rate"],
"outputs": ["optimal_power_setpoint", "recommended_actions", "estimated_savings", "confidence"]
},
"production_optimization": {
"name": "Production Efficiency Optimizer",
"description": "Maximizes production efficiency and throughput",
"parameters": ["raw_material_quality", "machine_utilization", "operator_skill"],
"outputs": ["optimal_production_rate", "efficiency_gain", "recommended_adjustments"]
},
"cost_optimization": {
"name": "Cost Reduction Optimizer",
"description": "Minimizes operational costs while maintaining quality",
"parameters": ["energy_cost", "labor_cost", "maintenance_cost"],
"outputs": ["optimal_cost_structure", "cost_reduction", "implementation_plan"]
}
}
# Optimization history
optimization_history = []
def generate_optimization_id():
"""Generate unique optimization ID"""
return f"OPT_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{random.randint(1000, 9999)}"
def run_energy_optimization(data):
"""Run energy optimization"""
power_load = data.get("power_load", 450.0)
time_of_day = data.get("time_of_day", 12)
production_rate = data.get("production_rate", 95.0)
# Mock optimization logic
if time_of_day >= 6 and time_of_day <= 18:
# Daytime optimization
optimal_power = power_load * 0.85 # Reduce power during peak hours
savings = power_load * 0.15 * 0.12 # 15% reduction at $0.12/kWh
else:
# Nighttime optimization
optimal_power = power_load * 0.95 # Slight reduction at night
savings = power_load * 0.05 * 0.08 # 5% reduction at $0.08/kWh
# Adjust based on production rate
if production_rate < 80:
optimal_power *= 0.9
savings *= 1.1
elif production_rate > 95:
optimal_power *= 1.05
savings *= 0.9
return {
"optimal_power_setpoint": round(optimal_power, 2),
"recommended_actions": [
"Adjust compressor speed to 85%",
"Optimize pump sequencing",
"Implement variable frequency drive"
],
"estimated_savings": round(savings, 2),
"confidence": random.uniform(0.85, 0.95)
}
def run_production_optimization(data):
"""Run production optimization"""
raw_material_quality = data.get("raw_material_quality", 85.0)
machine_utilization = data.get("machine_utilization", 92.0)
operator_skill = data.get("operator_skill", 88.0)
# Mock optimization logic
base_rate = 100.0
# Adjust based on factors
quality_factor = raw_material_quality / 100.0
utilization_factor = machine_utilization / 100.0
skill_factor = operator_skill / 100.0
optimal_rate = base_rate * quality_factor * utilization_factor * skill_factor
efficiency_gain = (optimal_rate - base_rate) / base_rate * 100
return {
"optimal_production_rate": round(optimal_rate, 2),
"efficiency_gain": round(efficiency_gain, 2),
"recommended_adjustments": [
"Increase raw material inspection frequency",
"Optimize machine maintenance schedule",
"Provide operator training on efficiency techniques"
]
}
def run_cost_optimization(data):
"""Run cost optimization"""
energy_cost = data.get("energy_cost", 55.0)
labor_cost = data.get("labor_cost", 30.0)
maintenance_cost = data.get("maintenance_cost", 15.0)
total_cost = energy_cost + labor_cost + maintenance_cost
# Mock optimization logic
optimal_energy = energy_cost * 0.9 # 10% reduction
optimal_labor = labor_cost * 0.95 # 5% reduction
optimal_maintenance = maintenance_cost * 1.05 # 5% increase for better maintenance
optimal_total = optimal_energy + optimal_labor + optimal_maintenance
cost_reduction = total_cost - optimal_total
return {
"optimal_cost_structure": {
"energy": round(optimal_energy, 2),
"labor": round(optimal_labor, 2),
"maintenance": round(optimal_maintenance, 2),
"total": round(optimal_total, 2)
},
"cost_reduction": round(cost_reduction, 2),
"implementation_plan": [
"Implement energy monitoring system",
"Optimize workforce scheduling",
"Increase preventive maintenance frequency"
]
}
def generate_forecast(hours=24):
"""Generate forecast data"""
forecast = []
base_time = datetime.now()
for i in range(hours):
timestamp = base_time + timedelta(hours=i)
hour = timestamp.hour
# Generate realistic forecast data
if hour >= 6 and hour <= 18:
# Daytime values
energy_consumption = random.uniform(450, 550)
production_rate = random.uniform(95, 105)
efficiency = random.uniform(85, 92)
cost = random.uniform(50, 60)
else:
# Nighttime values
energy_consumption = random.uniform(350, 450)
production_rate = random.uniform(80, 95)
efficiency = random.uniform(78, 85)
cost = random.uniform(40, 50)
forecast.append({
"timestamp": timestamp.isoformat(),
"energy_consumption": round(energy_consumption, 2),
"production_rate": round(production_rate, 2),
"efficiency": round(efficiency, 2),
"cost": round(cost, 2)
})
return forecast
@app.route('/health', methods=['GET'])
def health():
"""Health check endpoint"""
return jsonify({
"status": "healthy",
"service": "mock-optimizer",
"timestamp": datetime.now().isoformat(),
"models_available": len(optimization_models)
})
@app.route('/api/v1/models', methods=['GET'])
def get_models():
"""Get available optimization models"""
return jsonify({
"models": optimization_models,
"timestamp": datetime.now().isoformat()
})
@app.route('/api/v1/optimize/<model_name>', methods=['POST'])
def run_optimization(model_name):
"""Run optimization with specified model"""
if model_name not in optimization_models:
return jsonify({"error": f"Model '{model_name}' not found"}), 404
data = request.json
if not data:
return jsonify({"error": "No data provided"}), 400
start_time = time.time()
# Run appropriate optimization
if model_name == "energy_optimization":
result = run_energy_optimization(data)
elif model_name == "production_optimization":
result = run_production_optimization(data)
elif model_name == "cost_optimization":
result = run_cost_optimization(data)
else:
return jsonify({"error": "Model not implemented"}), 501
processing_time = round(time.time() - start_time, 3)
optimization_id = generate_optimization_id()
# Add to history
optimization_history.append({
"optimization_id": optimization_id,
"model": model_name,
"timestamp": datetime.now().isoformat(),
"processing_time": processing_time
})
return jsonify({
"optimization_id": optimization_id,
"model": model_name,
"result": result,
"processing_time": processing_time,
"timestamp": datetime.now().isoformat()
})
@app.route('/api/v1/history', methods=['GET'])
def get_history():
"""Get optimization history"""
return jsonify({
"history": optimization_history[-10:], # Last 10 optimizations
"total_optimizations": len(optimization_history),
"timestamp": datetime.now().isoformat()
})
@app.route('/api/v1/forecast', methods=['POST'])
def generate_optimization_forecast():
"""Generate optimization forecast"""
data = request.json or {}
hours = data.get("hours", 24)
if hours > 168: # Max 1 week
return jsonify({"error": "Forecast horizon too long. Maximum 168 hours (1 week)"}), 400
forecast = generate_forecast(hours)
return jsonify({
"forecast": forecast,
"generated_at": datetime.now().isoformat(),
"horizon_hours": hours
})
@app.route('/api/v1/status/<optimization_id>', methods=['GET'])
def get_optimization_status(optimization_id):
"""Get status of specific optimization"""
for opt in optimization_history:
if opt["optimization_id"] == optimization_id:
return jsonify({
"optimization_id": optimization_id,
"status": "completed",
"model": opt["model"],
"completed_at": opt["timestamp"],
"processing_time": opt["processing_time"]
})
return jsonify({"error": f"Optimization '{optimization_id}' not found"}), 404
if __name__ == '__main__':
print("🧠 Starting Mock Optimizer Server on port 8082...")
print("📊 Available endpoints:")
print(" GET /health")
print(" GET /api/v1/models")
print(" POST /api/v1/optimize/<model_name>")
print(" GET /api/v1/history")
print(" POST /api/v1/forecast")
print(" GET /api/v1/status/<optimization_id>")
app.run(host='0.0.0.0', port=8082, debug=False)