Matlab/Simulink: How to receive MATLAB commands via HTTP GET request
This example shows how to receive MATLAB commands via HTTP GET request.
In our previous example Matlab TCP/IP command server without any toolboxes we showed how to create a TCP/IP server in MATLAB without resorting to toolbox-only commands. However, even when being run using a Matlab Timer, it will block the GUI completely since Matlab inherently runs in a single-threaded way.
In this example, we’ll use a different strategy: Matlab itself is commanded via a Timer to periodically issue a HTTP request to an external Webserver. The webserver will then respond with a command to be executed in Matlab.
In this example, there is no feedback whatsoever on the output of the command!
Main MATLAB request function
function http_command()
% Function to execute MATLAB commands received via HTTP
try
% URL for the HTTP request
url = 'http://127.0.0.1:17231/command';
% Send HTTP request and receive response
options = weboptions('Timeout', 0.1, 'ContentType', 'text');
response = webread(url, options);
% Check status code (webread throws an exception for non-200 responses)
% If we're here, the status code was 200
% Check if the response is not empty
if ~isempty(response)
% Split response into lines
commandLines = strsplit(response, '\n');
% Execute each line as a MATLAB command
for i = 1:length(commandLines)
commandLine = strtrim(commandLines{i});
% Skip empty lines
if ~isempty(commandLine)
try
disp(['Executing command: ', commandLine]);
evalc(commandLine); % evalc suppresses standard output
catch cmdError
warning('Error executing command "%s": %s', ...
commandLine, cmdError.message);
end
end
end
else
disp('Empty response received from server.');
end
catch httpError
% Error handling for HTTP errors
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
end
MATLAB Timer
function http_command_timer()
% Creates a timer that calls executeHttpCommands() every 0.5 seconds
% If a timer with this name already exists, delete it
existingTimer = timerfind('Name', 'HttpCommandTimer');
if ~isempty(existingTimer)
stop(existingTimer);
delete(existingTimer);
disp('Existing timer was stopped and deleted.');
end
% Create new timer
t = timer('Name', 'HttpCommandTimer', ...
'Period', 0.5, ... % Timer interval (0.5 seconds)
'ExecutionMode', 'fixedRate', ... % Fixed repeat rate
'TimerFcn', @(~,~)http_command(), ... % Function to be called
'ErrorFcn', @(~,~)disp('Error executing HTTP command'));
% Start timer
start(t);
disp('HTTP Command Timer started. Calls executeHttpCommands() every 0.5 seconds.');
disp('Use stopHttpCommandTimer() to stop the timer.');
end
Python server
This simple example server will issue commands to alternatingly switch on and off a manual switch.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class CommandServer(BaseHTTPRequestHandler):
# Class variable to track state
toggle_state = False
def do_GET(self):
if self.path == '/command':
# Prepare alternating command
if CommandServer.toggle_state:
command = "set_param('printit/Manual Switch', 'sw', '1');"
else:
command = "set_param('printit/Manual Switch', 'sw', '0');"
# Toggle state for next request
CommandServer.toggle_state = not CommandServer.toggle_state
# Send HTTP response
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 error for all other paths
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()