def _exec_plan(self, filename, state, config, cancel): try: os.nice(5) hid = plan_hash(filename, config) base = 'plans/' + filename + '.' + hid files = [ base + '.json', base + '.positions.gz', base + '.speeds.gz'] found = True for path in files: if not os.path.exists(path): found = False if not found: self._clean_plans(filename) # Clean up old plans path = os.path.abspath('upload/' + filename) with tempfile.TemporaryDirectory() as tmpdir: cmd = ( '/usr/bin/env', 'python3', bbctrl.get_resource('plan.py'), path, json.dumps(state), json.dumps(config), '--max-time=%s' % self.max_plan_time, '--max-loop=%s' % self.max_loop_time ) log.info('Running: %s', cmd) with subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE, cwd = tmpdir) as proc: for line in proc.stdout: self._progress(filename, float(line)) if cancel.is_set(): proc.terminate() return out, errs = proc.communicate() self._progress(filename, 1) if cancel.is_set(): return if proc.returncode: log.error('Plan failed: ' + errs.decode('utf8')) return # Failed os.rename(tmpdir + '/meta.json', files[0]) os.rename(tmpdir + '/positions.gz', files[1]) os.rename(tmpdir + '/speeds.gz', files[2]) with open(files[0], 'r') as f: meta = json.load(f) with open(files[1], 'rb') as f: positions = f.read() with open(files[2], 'rb') as f: speeds = f.read() return meta, positions, speeds except Exception as e: log.exception(e)
def __init__(self, ctrl): self.ctrl = ctrl self.version = pkg_resources.require('bbctrl')[0].version default_config['version'] = self.version # Load config template with open(bbctrl.get_resource('http/config-template.json'), 'r', encoding = 'utf-8') as f: self.template = json.load(f)
def __init__(self, ctrl): self.ctrl = ctrl handlers = [ (r'/websocket', WSConnection), (r'/api/log', LogHandler), (r'/api/bugreport', BugReportHandler), (r'/api/reboot', RebootHandler), (r'/api/hostname', HostnameHandler), (r'/api/wifi', WifiHandler), (r'/api/remote/username', UsernameHandler), (r'/api/remote/password', PasswordHandler), (r'/api/config/load', ConfigLoadHandler), (r'/api/config/download', ConfigDownloadHandler), (r'/api/config/save', ConfigSaveHandler), (r'/api/config/reset', ConfigResetHandler), (r'/api/firmware/update', FirmwareUpdateHandler), (r'/api/upgrade', UpgradeHandler), (r'/api/file(/[^/]+)?', bbctrl.FileHandler), (r'/api/path/([^/]+)((/positions)|(/speeds))?', PathHandler), (r'/api/home(/[xyzabcXYZABC]((/set)|(/clear))?)?', HomeHandler), (r'/api/start', StartHandler), (r'/api/estop', EStopHandler), (r'/api/clear', ClearHandler), (r'/api/stop', StopHandler), (r'/api/pause', PauseHandler), (r'/api/unpause', UnpauseHandler), (r'/api/pause/optional', OptionalPauseHandler), (r'/api/step', StepHandler), (r'/api/position/([xyzabcXYZABC])', PositionHandler), (r'/api/override/feed/([\d.]+)', OverrideFeedHandler), (r'/api/override/speed/([\d.]+)', OverrideSpeedHandler), (r'/api/modbus/read', ModbusReadHandler), (r'/api/modbus/write', ModbusWriteHandler), (r'/api/jog', JogHandler), (r'/api/video', bbctrl.VideoHandler), (r'/(.*)', StaticFileHandler, { 'path': bbctrl.get_resource('http/'), "default_filename": "index.html" }), ] router = sockjs.tornado.SockJSRouter(SockJSConnection, '/sockjs') router.ctrl = ctrl tornado.web.Application.__init__(self, router.urls + handlers) try: self.listen(ctrl.args.port, address=ctrl.args.addr) except Exception as e: log.error('Failed to bind %s:%d: %s', ctrl.args.addr, ctrl.args.port, e) sys.exit(1) log.info('Listening on http://%s:%d/', ctrl.args.addr, ctrl.args.port)
def _exec(self): self.clean() # Clean up old plans with tempfile.TemporaryDirectory() as tmpdir: cmd = ( '/usr/bin/env', 'python3', bbctrl.get_resource('plan.py'), os.path.abspath(self.gcode), json.dumps(self.state), json.dumps(self.config), '--max-time=%s' % self.preplanner.max_plan_time, '--max-loop=%s' % self.preplanner.max_loop_time ) self.preplanner.log.info('Running: %s', cmd) proc = process.Subprocess(cmd, stdout = process.Subprocess.STREAM, stderr = process.Subprocess.STREAM, cwd = tmpdir) errs = '' self.pid = proc.proc.pid try: try: while True: line = yield proc.stdout.read_until(b'\n') self.progress = float(line.strip()) if self.cancel: return except iostream.StreamClosedError: pass self.progress = 1 ret = yield proc.wait_for_exit(False) if ret: errs = yield proc.stderr.read_until_close() raise Exception('Plan failed: ' + errs.decode('utf8')) finally: proc.stderr.close() proc.stdout.close() if not self.cancel: os.rename(tmpdir + '/meta.json', self.files[0]) os.rename(tmpdir + '/positions.gz', self.files[1]) os.rename(tmpdir + '/speeds.gz', self.files[2]) os.sync()
def load_files(self): self.files = [] upload = self.ctrl.get_upload() if not os.path.exists(upload): os.mkdir(upload) from shutil import copy copy(bbctrl.get_resource('http/buildbotics.nc'), upload) for path in os.listdir(upload): if os.path.isfile(upload + '/' + path): self.files.append(path) self.files.sort() self.set('files', self.files) if len(self.files): self.select_file(self.files[0]) else: self.select_file('')
def __init__(self, ctrl): self.ctrl = ctrl self.config_vars = {} try: self.version = pkg_resources.require('bbctrl')[0].version default_config['version'] = self.version # Load config template with open(bbctrl.get_resource('http/config-template.json'), 'r', encoding = 'utf-8') as f: self.template = json.load(f) # Add all sections from template to default config for section in self.template: if not section in default_config: default_config[section] = {} except Exception as e: log.exception(e)
def __init__(self, args, ioloop): self.args = args self.ioloop = ioloop self.ctrls = {} # Init camera if not args.disable_camera: if self.args.demo: log = bbctrl.log.Log(args, ioloop, 'camera.log') else: log = self.get_ctrl().log self.camera = bbctrl.Camera(ioloop, args, log) else: self.camera = None # Init controller if not self.args.demo: self.get_ctrl() self.monitor = bbctrl.MonitorTemp(self) handlers = [ (r'/websocket', WSConnection), (r'/api/log', LogHandler), (r'/api/bugreport', BugReportHandler), (r'/api/reboot', RebootHandler), (r'/api/hostname', HostnameHandler), (r'/api/wifi', WifiHandler), (r'/api/remote/username', UsernameHandler), (r'/api/remote/password', PasswordHandler), (r'/api/config/load', ConfigLoadHandler), (r'/api/config/download', ConfigDownloadHandler), (r'/api/config/save', ConfigSaveHandler), (r'/api/config/reset', ConfigResetHandler), (r'/api/firmware/update', FirmwareUpdateHandler), (r'/api/upgrade', UpgradeHandler), (r'/api/file(/[^/]+)?', bbctrl.FileHandler), (r'/api/path/([^/]+)((/positions)|(/speeds))?', PathHandler), (r'/api/home(/[xyzabcXYZABC]((/set)|(/clear))?)?', HomeHandler), (r'/api/start', StartHandler), (r'/api/estop', EStopHandler), (r'/api/clear', ClearHandler), (r'/api/stop', StopHandler), (r'/api/pause', PauseHandler), (r'/api/unpause', UnpauseHandler), (r'/api/pause/optional', OptionalPauseHandler), (r'/api/step', StepHandler), (r'/api/position/([xyzabcXYZABC])', PositionHandler), (r'/api/override/feed/([\d.]+)', OverrideFeedHandler), (r'/api/override/speed/([\d.]+)', OverrideSpeedHandler), (r'/api/modbus/read', ModbusReadHandler), (r'/api/modbus/write', ModbusWriteHandler), (r'/api/jog', JogHandler), (r'/api/video', bbctrl.VideoHandler), (r'/(.*)', StaticFileHandler, { 'path': bbctrl.get_resource('http/'), 'default_filename': 'index.html' }), ] router = sockjs.tornado.SockJSRouter(SockJSConnection, '/sockjs') router.app = self tornado.web.Application.__init__(self, router.urls + handlers) try: self.listen(args.port, address=args.addr) except Exception as e: raise Exception('Failed to bind %s:%d: %s' % (args.addr, args.port, e)) print('Listening on http://%s:%d/' % (args.addr, args.port))
def _get_image_resource(self, path): path = bbctrl.get_resource(path) with open(path, 'rb') as f: return self._format_frame(f.read())
def get_image_resource(self, name): return bbctrl.get_resource('http/images/%s.jpg' % name)