summaryrefslogtreecommitdiff
path: root/robot
diff options
context:
space:
mode:
Diffstat (limited to 'robot')
-rwxr-xr-xrobot/main.py58
1 files changed, 42 insertions, 16 deletions
diff --git a/robot/main.py b/robot/main.py
index b25f748..0b718b7 100755
--- a/robot/main.py
+++ b/robot/main.py
@@ -21,15 +21,17 @@
PORT = 8000
+from fcntl import fcntl, F_GETFL, F_SETFL
+import io
import json
-import multiprocessing
import os
import os.path
import signal
+import subprocess
+import time
import engineio
import eventlet
-
import ev3dev
ev3_names = {
@@ -47,18 +49,32 @@ ev3_motors = [
]
connections = set()
-process = None
-
-def _run_exec(program):
- import ev3dev
- from mindstorms_widgets import mindstorms_widgets
- exec(program)
+running = False
+
+# Make a Python interpreter ready for running user program.
+def start_interpreter():
+ global running
+ process = subprocess.Popen(['python3', '-u'], bufsize=1, universal_newlines=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ # Set the non-blocking flag for stdout.
+ flags = fcntl(process.stdout.fileno(), F_GETFL)
+ fcntl(process.stdout.fileno(), F_SETFL, flags | os.O_NONBLOCK)
+ process.stdin.write("import ev3dev\n")
+ process.stdin.write("from mindstorms_widgets import mindstorms_widgets\n")
+ running = False
+ return process
+
+process = start_interpreter()
def run(program):
- global process
- stop()
- process = multiprocessing.Process(target=_run_exec, args=[program])
- process.start()
+ global process, running
+ if running:
+ stop()
+ running = True
+ process.stdin.write("exec('''" + program + "''')\n")
+ process.stdin.close()
def stop():
global process
@@ -67,16 +83,16 @@ def stop():
os.kill(process.pid, signal.SIGKILL)
except:
pass
- process = None
-
for motor in ev3_motors:
if motor.connected:
motor.stop(stop_command='brake')
+ process = start_interpreter()
def notifier():
+ global process
+
sensors_path = '/sys/class/lego-sensor'
sensors = {}
-
for sensor in os.listdir(sensors_path):
path = os.path.join(sensors_path, sensor)
with open(os.path.join(path, 'driver_name'), 'r') as f:
@@ -90,8 +106,17 @@ def notifier():
sensors[path] = (friendly_name, multiplier, unit)
while True:
- eventlet.sleep(0.2)
try:
+ if running:
+ text = process.stdout.readline()
+ if text:
+ message = {'event': 'output', 'text': text}
+ for sid in connections:
+ eio.send(sid, json.dumps(message))
+ continue
+ if process.poll() is not None:
+ process = start_interpreter()
+
message = {'event': 'update', 'sensors': {}}
for path, (name, multiplier, unit) in sorted(sensors.items()):
with open(os.path.join(path, 'value0'), 'rb') as f:
@@ -105,6 +130,7 @@ def notifier():
eio.send(sid, text)
except:
pass
+ eventlet.sleep(0.2)
eio = engineio.Server(async_mode='eventlet', cookie=None)
app = engineio.Middleware(eio)