diff --git a/ESP_api/ESP_api.ino b/ESP_api/ESP_api.ino index caac68b..556a338 100644 --- a/ESP_api/ESP_api.ino +++ b/ESP_api/ESP_api.ino @@ -3,7 +3,7 @@ #include #include #include "esp_mac.h" -//ver 1.03 +//ver 1.04 // Constants for Access Point mode const char* ap_ssid = "ESP32-AP"; const char* ap_password = "12345678"; @@ -25,6 +25,9 @@ bool isAPMode = false; // Variable to keep track of the last log time unsigned long lastLogTime = 0; +// Array to keep track of the previous state of each input pin +bool previousInputState[4] = {HIGH, HIGH, HIGH, HIGH}; + // Function to send logs to the log server void sendLog(String message) { if (WiFi.status() == WL_CONNECTED && logServerIP.length() > 0 && logServerPort.length() > 0) { @@ -184,6 +187,19 @@ void loop() { sendLog("Board is functioning"); lastLogTime = millis(); } + + // Check the state of each input pin and log changes + for (int i = 0; i < 4; i++) { + bool currentState = digitalRead(inputPins[i]); + if (currentState != previousInputState[i]) { + if (currentState == LOW) { + sendLog("Input " + String(i + 1) + " pressed"); + } else { + sendLog("Input " + String(i + 1) + " released"); + } + previousInputState[i] = currentState; + } + } } void startAPMode() { diff --git a/server_api/app.py b/server_api/app.py index fe87f12..8a8efa5 100644 --- a/server_api/app.py +++ b/server_api/app.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta import os import threading import requests +import base64 app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///logs.db' @@ -25,6 +26,10 @@ class Log(db.Model): 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='') # Create the database if it does not exist if not os.path.exists('instance/logs.db'): @@ -58,6 +63,10 @@ def log_message(): input2_status = latest_log.input2_status if latest_log else 'off' input3_status = latest_log.input3_status if latest_log else 'off' input4_status = latest_log.input4_status if latest_log else 'off' + mission1 = latest_log.mission1 if latest_log else '' + mission2 = latest_log.mission2 if latest_log else '' + mission3 = latest_log.mission3 if latest_log else '' + mission4 = latest_log.mission4 if latest_log else '' if hostname and ip_address and message: # Parse the message to update relay status @@ -81,19 +90,28 @@ def log_message(): action = 'on' if "pressed" in message else 'off' if input_index == 1: input1_status = action + if action == 'on': + execute_mission(mission1) elif input_index == 2: input2_status = action + if action == 'on': + execute_mission(mission2) elif input_index == 3: input3_status = action + if action == 'on': + execute_mission(mission3) elif input_index == 4: input4_status = action + if action == 'on': + execute_mission(mission4) new_log = Log( hostname=hostname, ip_address=ip_address, message=message, relay1_status=relay1_status, relay2_status=relay2_status, relay3_status=relay3_status, relay4_status=relay4_status, input1_status=input1_status, input2_status=input2_status, - input3_status=input3_status, input4_status=input4_status + input3_status=input3_status, input4_status=input4_status, + mission1=mission1, mission2=mission2, mission3=mission3, mission4=mission4 ) db.session.add(new_log) db.session.commit() @@ -162,7 +180,8 @@ def view_board(hostname): def delete_board(hostname): Log.query.filter_by(hostname=hostname).delete() db.session.commit() - return redirect(url_for('index')) + flash(f'Board {hostname} and its settings have been deleted.', 'success') + return redirect(url_for('settings')) @app.route('/board//logs', methods=['GET']) def get_board_logs(hostname): @@ -205,7 +224,11 @@ def settings(): 'input1': latest_log.input1_status if latest_log else 'off', 'input2': latest_log.input2_status if latest_log else 'off', 'input3': latest_log.input3_status if latest_log else 'off', - 'input4': latest_log.input4_status if latest_log else 'off' + 'input4': latest_log.input4_status if latest_log else 'off', + 'mission1': latest_log.mission1 if latest_log else '', + 'mission2': latest_log.mission2 if latest_log else '', + 'mission3': latest_log.mission3 if latest_log else '', + 'mission4': latest_log.mission4 if latest_log else '' }) return render_template('settings.html', cleanup_time=cleanup_time, mir_ip=mir_ip, mir_user=mir_user, mir_password=mir_password, boards=board_settings) @@ -239,13 +262,21 @@ def set_board_settings(hostname): input2 = request.form.get('input2') input3 = request.form.get('input3') input4 = request.form.get('input4') - if input1 and input2 and input3 and input4: + mission1 = request.form.get('mission1') + mission2 = request.form.get('mission2') + mission3 = request.form.get('mission3') + mission4 = request.form.get('mission4') + if input1 and input2 and input3 and input4 and mission1 and mission2 and mission3 and mission4: latest_log = Log.query.filter_by(hostname=hostname).order_by(Log.timestamp.desc()).first() if latest_log: latest_log.input1_status = input1 latest_log.input2_status = input2 latest_log.input3_status = input3 latest_log.input4_status = input4 + latest_log.mission1 = mission1 + latest_log.mission2 = mission2 + latest_log.mission3 = mission3 + latest_log.mission4 = mission4 db.session.commit() flash('Board settings updated successfully!', 'success') else: @@ -263,6 +294,19 @@ def run_cleanup_now(): flash('Cleanup executed successfully!', 'success') return redirect(url_for('settings')) +@app.route('/board//input_status', methods=['GET']) +def get_input_status(hostname): + log = Log.query.filter_by(hostname=hostname).order_by(Log.timestamp.desc()).first() + if log: + input_status = [ + log.input1_status, + log.input2_status, + log.input3_status, + log.input4_status + ] + return jsonify({'input_status': input_status}) + return jsonify({'input_status': ['off', 'off', 'off', 'off']}) + def post_action_to_server(hostname, action): url = "http://your-server-url.com/action" payload = { @@ -278,6 +322,24 @@ 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 schedule_cleanup(): with app.app_context(): cutoff_date = datetime.utcnow() - timedelta(hours=app.config.get('CLEANUP_TIME', 24)) diff --git a/server_api/instance/logs.db b/server_api/instance/logs.db index fcaa639..2aaf7b0 100644 Binary files a/server_api/instance/logs.db and b/server_api/instance/logs.db differ diff --git a/server_api/templates/board.html b/server_api/templates/board.html index c08677f..c8f28bb 100644 --- a/server_api/templates/board.html +++ b/server_api/templates/board.html @@ -107,11 +107,11 @@

Input Status

-
    +
      {% for i in range(4) %}
    • Input {{ i + 1 }} - {{ input_status[i] }} + {{ input_status[i] }}
    • {% endfor %}
    @@ -158,7 +158,7 @@ .then(data => { const logList = document.getElementById('log-list'); logList.innerHTML = ''; - data.logs.reverse().forEach(log => { // Reverse the order to show newest first + data.logs.forEach(log => { // Keep the order as newest first const logItem = document.createElement('li'); logItem.className = 'list-group-item'; logItem.innerHTML = `${log.timestamp}: ${log.message}`; @@ -169,6 +169,19 @@ .catch(error => console.error('Error fetching logs:', error)); } + function fetchInputStatus() { + fetch(`/board/{{ hostname }}/input_status`) + .then(response => response.json()) + .then(data => { + for (let i = 0; i < 4; i++) { + const inputStatus = document.getElementById(`input-status-${i + 1}`); + inputStatus.className = `badge badge-${data.input_status[i] === 'on' ? 'success' : 'secondary'}`; + inputStatus.innerText = data.input_status[i]; + } + }) + .catch(error => console.error('Error fetching input status:', error)); + } + function startTimer() { let timer = 5; const timerElement = document.getElementById('timer'); @@ -179,6 +192,7 @@ } else { timer = 5; fetchLogs(); + fetchInputStatus(); } }, 1000); } diff --git a/server_api/templates/index.html b/server_api/templates/index.html index 186214b..048c852 100644 --- a/server_api/templates/index.html +++ b/server_api/templates/index.html @@ -58,9 +58,6 @@

    Status: {{ board.status }}

    Last Seen: {{ board.last_seen }}

    View Details -
    - -
diff --git a/server_api/templates/settings.html b/server_api/templates/settings.html index 592c1c4..4363ad3 100644 --- a/server_api/templates/settings.html +++ b/server_api/templates/settings.html @@ -51,15 +51,15 @@
Set Cleanup Time
-
+
- - + +
- -
-
- + + + +
@@ -91,22 +91,27 @@
Board: {{ board.hostname }}
- - + +
- - + +
- - + +
- - + + +
+
+ + + +
-