database separate file
This commit is contained in:
@@ -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
33
server_api/mir_server.py
Normal 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
45
server_api/models.py
Normal 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')
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user