Matlab/Simulink: Wie man MATLAB-Befehle über HTTP-GET-Request empfängt
Dieses Beispiel zeigt, wie man MATLAB-Befehle über HTTP-GET-Request empfängt.
In unserem vorherigen Beispiel Matlab TCP/IP-Befehlsserver ohne jegliche Toolboxes haben wir gezeigt, wie man einen TCP/IP-Server in MATLAB erstellt, ohne auf Toolbox-exklusive Befehle zurückzugreifen. Jedoch wird, selbst wenn er mit einem Matlab-Timer ausgeführt wird, die GUI komplett blockieren, da Matlab inhärent single-threaded läuft.
In diesem Beispiel werden wir eine andere Strategie verwenden: Matlab selbst wird über einen Timer angewiesen, periodisch einen HTTP-Request an einen externen Webserver zu senden. Der Webserver antwortet dann mit einem Befehl, der in Matlab ausgeführt werden soll.
In diesem Beispiel gibt es keinerlei Feedback zur Ausgabe des Befehls!
Haupt-MATLAB-Request-Funktion
function http_command()
% Funktion zum Ausführen von MATLAB-Befehlen, die über HTTP empfangen wurden
try
% URL für den HTTP-Request
url = 'http://127.0.0.1:17231/command';
% HTTP-Request senden und Antwort empfangen
options = weboptions('Timeout', 0.1, 'ContentType', 'text');
response = webread(url, options);
% Statuscode prüfen (webread wirft eine Exception bei Nicht-200-Antworten)
% Wenn wir hier sind, war der Statuscode 200
% Prüfen, ob die Antwort nicht leer ist
if ~isempty(response)
% Antwort in Zeilen aufteilen
commandLines = strsplit(response, '\n');
% Jede Zeile als MATLAB-Befehl ausführen
for i = 1:length(commandLines)
commandLine = strtrim(commandLines{i});
% Leere Zeilen überspringen
if ~isempty(commandLine)
try
disp(['Executing command: ', commandLine]);
evalc(commandLine); % evalc unterdrückt die Standardausgabe
catch cmdError
warning('Error executing command "%s": %s', ...
commandLine, cmdError.message);
end
end
end
else
disp('Empty response received from server.');
end
catch httpError
% Fehlerbehandlung für HTTP-Fehler
if contains(httpError.message, '404')
disp('HTTP 404: Resource not found.');
elseif contains(httpError.message, '500')
disp('HTTP 500: Server error.');
elseif contains(httpError.message, 'Connection')
disp('Connection error: Server possibly not reachable.');
else
disp(['HTTP error: ', httpError.message]);
end
end
endMATLAB-Timer
function http_command_timer()
% Erstellt einen Timer, der alle 0,5 Sekunden executeHttpCommands() aufruft
% Wenn ein Timer mit diesem Namen bereits existiert, lösche ihn
existingTimer = timerfind('Name', 'HttpCommandTimer');
if ~isempty(existingTimer)
stop(existingTimer);
delete(existingTimer);
disp('Existing timer was stopped and deleted.');
end
% Neuen Timer erstellen
t = timer('Name', 'HttpCommandTimer', ...
'Period', 0.5, ... % Timer-Intervall (0,5 Sekunden)
'ExecutionMode', 'fixedRate', ... % Feste Wiederholungsrate
'TimerFcn', @(~,~)http_command(), ... % Aufzurufende Funktion
'ErrorFcn', @(~,~)disp('Error executing HTTP command'));
% Timer starten
start(t);
disp('HTTP Command Timer started. Calls executeHttpCommands() every 0.5 seconds.');
disp('Use stopHttpCommandTimer() to stop the timer.');
endPython-Server
Dieser einfache Beispiel-Server wird Befehle ausgeben, um abwechselnd einen Manual-Switch ein- und auszuschalten.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class CommandServer(BaseHTTPRequestHandler):
# Klassenvariable zur Zustandsverfolgung
toggle_state = False
def do_GET(self):
if self.path == '/command':
# Wechselnden Befehl vorbereiten
if CommandServer.toggle_state:
command = "set_param('printit/Manual Switch', 'sw', '1');"
else:
command = "set_param('printit/Manual Switch', 'sw', '0');"
# Zustand für nächsten Request umschalten
CommandServer.toggle_state = not CommandServer.toggle_state
# HTTP-Antwort senden
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(command.encode('utf-8'))
print(f"Command sent: {command}")
else:
# 404-Fehler für alle anderen Pfade
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'404 Not Found')
def run_server(port=17231):
server_address = ('127.0.0.1', port)
httpd = HTTPServer(server_address, CommandServer)
print(f"Server running at http://127.0.0.1:{port}")
print("Press Ctrl+C to stop")
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
print("Server stopped")
if __name__ == '__main__':
run_server()