If you want to do this in real-time, I would investigate using UDP sockets, as they're fast and cheap.
As a test I created a modal operator who was on a timer and listened on a socket on each cycle.
Unfortunately, my modal operator arbitrarily appears to just stop. But as a quick test, this looks promising.
Create a cube. Start this python client (who sends random data).
import socket
import random
import time
UDP_IP = "127.0.0.1"
UDP_PORT = 5006
print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.connect((UDP_IP, UDP_PORT))
for i in range(1000):
time.sleep(0.02)
MESSAGE = str(random.randint(0, 5))
sock.send(MESSAGE.encode())
print(MESSAGE)
And run this modal operator in Blender.
import bpy
import socket
class ModalOperator(bpy.types.Operator):
bl_idname = "object.modal_operator"
bl_label = "Simple Modal Operator"
def modal (self, context, event):
if event.type == 'ESC':
context.window_manager.event_timer_remove(self._timer)
return {'CANCELLED'}
if event.type == 'TIMER_REPORT':
try:
data, addr = self.sock.recvfrom(1024)
self.cube.location.x = float(data)
except:
# timed out
pass
wm = context.window_manager
self._timer = wm.event_timer_add(0.2)
return {"PASS_THROUGH"}
def execute(self, context):
self.cube = bpy.data.objects['Cube']
print("creating socket")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind(("127.0.0.1", 5006))
self.sock.settimeout(0.18)
print("adding timer")
wm = context.window_manager
self._timer = wm.event_timer_add(0.2)
wm.modal_handler_add(self)
return {"RUNNING_MODAL"}
bpy.utils.register_class(ModalOperator)
bpy.ops.object.modal_operator('INVOKE_DEFAULT')