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)
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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()
示例#5
0
    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('')
示例#6
0
    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)
示例#7
0
    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))
示例#8
0
    def _get_image_resource(self, path):
        path = bbctrl.get_resource(path)

        with open(path, 'rb') as f:
            return self._format_frame(f.read())
示例#9
0
 def get_image_resource(self, name):
     return bbctrl.get_resource('http/images/%s.jpg' % name)