database separate file

This commit is contained in:
2025-03-14 11:43:12 +02:00
parent 5fcf4620dc
commit 7542f00327
5 changed files with 199 additions and 64 deletions

View File

@@ -1,53 +1,19 @@
from flask import Flask, request, jsonify, render_template, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, timedelta
import os
import threading
import requests
import base64
from .mir_server import execute_mission # Import the execute_mission function
from .models import db, Log, MirServerSettings, BoardSettings, MissionStatus # Import the models
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///logs.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = 'supersecretkey'
db = SQLAlchemy(app)
class Log(db.Model):
id = db.Column(db.Integer, primary_key=True)
hostname = db.Column(db.String(100), nullable=False)
ip_address = db.Column(db.String(100), nullable=False)
message = db.Column(db.String(500), nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
relay1_status = db.Column(db.String(3), default='off')
relay2_status = db.Column(db.String(3), default='off')
relay3_status = db.Column(db.String(3), default='off')
relay4_status = db.Column(db.String(3), default='off')
input1_status = db.Column(db.String(3), default='off')
input2_status = db.Column(db.String(3), default='off')
input3_status = db.Column(db.String(3), default='off')
input4_status = db.Column(db.String(3), default='off')
mission1 = db.Column(db.String(100), default='')
mission2 = db.Column(db.String(100), default='')
mission3 = db.Column(db.String(100), default='')
mission4 = db.Column(db.String(100), default='')
class MirServerSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(db.String(100), nullable=False)
user = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100), nullable=False)
auth_header = db.Column(db.String(500), nullable=False)
class BoardSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
hostname = db.Column(db.String(100), nullable=False)
mission1 = db.Column(db.String(100), nullable=False)
mission2 = db.Column(db.String(100), nullable=False)
mission3 = db.Column(db.String(100), nullable=False)
mission4 = db.Column(db.String(100), nullable=False)
db.init_app(app) # Initialize the database with the app
# Create the database if it does not exist
if not os.path.exists('instance/logs.db'):
os.makedirs('instance', exist_ok=True)
with app.app_context():
db.create_all()
@@ -101,6 +67,8 @@ def log_message():
action = 'on' if "pressed" in message else 'off'
if input_index == 1:
input1_status = action
if action == 'on':
initiate_mission(hostname, 1)
elif input_index == 2:
input2_status = action
elif input_index == 3:
@@ -235,10 +203,11 @@ def control_relay(hostname, relay, action):
@app.route('/settings', methods=['GET'])
def settings():
cleanup_time = app.config.get('CLEANUP_TIME', 24)
mir_ip = app.config.get('MIR_IP', '')
mir_user = app.config.get('MIR_USER', '')
mir_password = app.config.get('MIR_PASSWORD', '')
mir_auth_header = app.config.get('MIR_AUTH_HEADER', '')
mir_settings = MirServerSettings.query.first()
mir_ip = mir_settings.ip_address if mir_settings else ''
mir_user = mir_settings.user if mir_settings else ''
mir_password = mir_settings.password if mir_settings else ''
mir_auth_header = mir_settings.auth_header if mir_settings else ''
boards = BoardSettings.query.all()
board_settings = []
for board in boards:
@@ -268,10 +237,21 @@ def set_mir_server():
mir_password = request.form.get('mir_password')
mir_auth_header = request.form.get('mir_auth_header')
if mir_ip and mir_user and mir_password and mir_auth_header:
app.config['MIR_IP'] = mir_ip
app.config['MIR_USER'] = mir_user
app.config['MIR_PASSWORD'] = mir_password
app.config['MIR_AUTH_HEADER'] = mir_auth_header
mir_settings = MirServerSettings.query.first()
if mir_settings:
mir_settings.ip_address = mir_ip
mir_settings.user = mir_user
mir_settings.password = mir_password
mir_settings.auth_header = mir_auth_header
else:
mir_settings = MirServerSettings(
ip_address=mir_ip,
user=mir_user,
password=mir_password,
auth_header=mir_auth_header
)
db.session.add(mir_settings)
db.session.commit()
flash('MIR Server settings updated successfully!', 'success')
else:
flash('Invalid MIR Server settings!', 'danger')
@@ -327,6 +307,21 @@ def get_input_status(hostname):
return jsonify({'input_status': input_status})
return jsonify({'input_status': ['off', 'off', 'off', 'off']})
@app.route('/board/<hostname>/mission_status', methods=['GET'])
def get_mission_status(hostname):
mission_status = MissionStatus.query.filter_by(hostname=hostname).order_by(MissionStatus.id.desc()).first()
if mission_status:
return jsonify({
'step1': 'Started' if mission_status.status == 'Started' else 'Pending',
'step2': 'Pending',
'mission': mission_status.status
})
return jsonify({
'step1': 'Pending',
'step2': 'Pending',
'mission': 'Pending'
})
def post_action_to_server(hostname, action):
url = "http://your-server-url.com/action"
payload = {
@@ -342,23 +337,47 @@ def post_action_to_server(hostname, action):
except Exception as e:
print(f"Error posting action: {e}")
def execute_mission(mission_id):
mir_ip = app.config.get('MIR_IP')
mir_user = app.config.get('MIR_USER')
mir_password = app.config.get('MIR_PASSWORD')
url = f"http://{mir_ip}/api/v2.0.0/missions/{mission_id}/dispatch"
headers = {
'Content-Type': 'application/json',
'Authorization': f'Basic {base64.b64encode(f"{mir_user}:{mir_password}".encode()).decode()}'
}
try:
response = requests.post(url, headers=headers)
if response.status_code == 200:
print(f"Mission {mission_id} executed successfully.")
else:
print(f"Failed to execute mission {mission_id}: {response.text}")
except Exception as e:
print(f"Error executing mission {mission_id}: {e}")
def initiate_mission(hostname, input_index):
board_settings = BoardSettings.query.filter_by(hostname=hostname).first()
if not board_settings:
return
mission_id = getattr(board_settings, f'mission{input_index}')
if not mission_id:
return
execute_mission(mission_id, hostname)
mission_status = MissionStatus(hostname=hostname, mission_id=mission_id, status='Started')
db.session.add(mission_status)
db.session.commit()
def fetch_mission_status():
with app.app_context():
missions = MissionStatus.query.filter_by(status='Started').all()
mir_settings = MirServerSettings.query.first()
if not mir_settings:
print("MIR server settings not found.")
return
mir_ip = mir_settings.ip_address
auth_header = mir_settings.auth_header
headers = {
'Content-Type': 'application/json',
'Authorization': auth_header
}
for mission in missions:
url = f"http://{mir_ip}/api/v2.0.0/missions/{mission.mission_guid}" # Use mission_guid
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
mission_data = response.json()
mission.status = mission_data.get('state', 'Pending')
db.session.commit()
else:
print(f"Failed to fetch mission status {mission.mission_id}: {response.text}")
except Exception as e:
print(f"Error fetching mission status {mission.mission_id}: {e}")
threading.Timer(30, fetch_mission_status).start()
def schedule_cleanup():
with app.app_context():
@@ -369,4 +388,5 @@ def schedule_cleanup():
if __name__ == '__main__':
schedule_cleanup() # Start the cleanup scheduler
app.run(host='0.0.0.0', port=5000)
fetch_mission_status() # Start fetching mission status
app.run(host='0.0.0.0', port=80)

Binary file not shown.

33
server_api/mir_server.py Normal file
View File

@@ -0,0 +1,33 @@
import requests
from .models import MirServerSettings, MissionStatus
from . import db
def execute_mission(mission_id, hostname):
mir_settings = MirServerSettings.query.first()
if not mir_settings:
print("MIR server settings not found.")
return
mir_ip = mir_settings.ip_address
auth_header = mir_settings.auth_header
url = f"http://{mir_ip}/api/v2.0.0/mission_scheduler"
headers = {
'accept': 'application/json',
'Authorization': auth_header,
'Accept-Language': 'en_US',
'Content-Type': 'application/json'
}
try:
response = requests.post(url, headers=headers, json={"mission_id": mission_id})
if response.status_code in {200, 201}:
print(f"Mission {mission_id} executed successfully.")
mission_data = response.json()
mission_guid = mission_data.get('id')
mission_status = MissionStatus(hostname=hostname, mission_id=mission_id, mission_guid=mission_guid, status='Started')
db.session.add(mission_status)
db.session.commit()
else:
print(f"Failed to execute mission {mission_id}: {response.text}")
except Exception as e:
print(f"Error executing mission {mission_id}: {e}")

45
server_api/models.py Normal file
View File

@@ -0,0 +1,45 @@
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class Log(db.Model):
id = db.Column(db.Integer, primary_key=True)
hostname = db.Column(db.String(100), nullable=False)
ip_address = db.Column(db.String(100), nullable=False)
message = db.Column(db.String(500), nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
relay1_status = db.Column(db.String(3), default='off')
relay2_status = db.Column(db.String(3), default='off')
relay3_status = db.Column(db.String(3), default='off')
relay4_status = db.Column(db.String(3), default='off')
input1_status = db.Column(db.String(3), default='off')
input2_status = db.Column(db.String(3), default='off')
input3_status = db.Column(db.String(3), default='off')
input4_status = db.Column(db.String(3), default='off')
mission1 = db.Column(db.String(100), default='')
mission2 = db.Column(db.String(100), default='')
mission3 = db.Column(db.String(100), default='')
mission4 = db.Column(db.String(100), default='')
class MirServerSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(db.String(100), nullable=False)
user = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100), nullable=False)
auth_header = db.Column(db.String(500), nullable=False)
class BoardSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
hostname = db.Column(db.String(100), nullable=False)
mission1 = db.Column(db.String(100), nullable=False)
mission2 = db.Column(db.String(100), nullable=False)
mission3 = db.Column(db.String(100), nullable=False)
mission4 = db.Column(db.String(100), nullable=False)
class MissionStatus(db.Model):
id = db.Column(db.Integer, primary_key=True)
hostname = db.Column(db.String(100), nullable=False)
mission_id = db.Column(db.String(100), nullable=False)
mission_guid = db.Column(db.String(100), nullable=True) # Add this field
status = db.Column(db.String(100), nullable=False, default='Pending')

View File

@@ -149,6 +149,28 @@
</div>
</div>
</div>
<div class="col-md-6">
<h3>MIR Mission Status</h3>
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Mission Execution Steps</h5>
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-center">
Step 1: Receiving start trigger from the board input
<span id="step-1-status" class="badge badge-secondary">Pending</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
Step 2: Posting mission to MIR server
<span id="step-2-status" class="badge badge-secondary">Pending</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
Step 3: Mission execution status
<span id="mission-status" class="badge badge-secondary">Pending</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script>
@@ -182,6 +204,20 @@
.catch(error => console.error('Error fetching input status:', error));
}
function fetchMissionStatus() {
fetch(`/board/{{ hostname }}/mission_status`)
.then(response => response.json())
.then(data => {
document.getElementById('step-1-status').className = `badge badge-${data.step1}`;
document.getElementById('step-1-status').innerText = data.step1;
document.getElementById('step-2-status').className = `badge badge-${data.step2}`;
document.getElementById('step-2-status').innerText = data.step2;
document.getElementById('mission-status').className = `badge badge-${data.mission}`;
document.getElementById('mission-status').innerText = data.mission;
})
.catch(error => console.error('Error fetching mission status:', error));
}
function startTimer() {
let timer = 5;
const timerElement = document.getElementById('timer');
@@ -199,6 +235,7 @@
document.addEventListener('DOMContentLoaded', () => {
startTimer();
setInterval(fetchMissionStatus, 30000); // Fetch mission status every 30 seconds
});
</script>
</body>