Exemple #1
0
def main():
    if options.reset:
        print("Clearing all configuration values.")
        try:
            os.remove(os.path.expanduser('~/.config/spiro/spiro.conf'))
        except OSError as e:
            print("Could not remove file (~/.config/spiro/spiro.conf):",
                  e.strerror)
            raise
    if options.install:
        print("Installing systemd service file.")
        installService()
    if options.resetpw:
        print("Resetting web UI password.")
        cfg.set('password', '')
    if options.toggle_debug:
        cfg.set('debug', not cfg.get('debug'))
        if cfg.get('debug'):
            print("Debug mode on.")
        else:
            print("Debug mode off")
    if any([
            options.reset, options.resetpw, options.install,
            options.toggle_debug
    ]):
        sys.exit()

    # no options given, go ahead and start web ui
    global cam
    gpio.setmode(gpio.BCM)
    hw.GPIOInit()
    cam = initCam()
    log('Starting web UI.')
    webui.start(cam, hw)
Exemple #2
0
def experiment():
    if request.method == 'POST':
        if request.form['action'] == 'start':
            if experimenter.running:
                flash("Experiment is already running.")
            else:
                if request.form.get('duration'): experimenter.duration = int(request.form['duration'])
                else: experimenter.duration = 7
                if request.form.get('delay'): experimenter.delay = int(request.form['delay'])
                else: experimenter.delay = 60
                if request.form.get('directory'): experimenter.dir = os.path.expanduser(os.path.join('~', request.form['directory'].replace('/', '-')))
                else: experimenter.dir = os.path.expanduser('~')
                setLive('off')
                log("Starting new experiment.")
                experimenter.next_status = 'run'
                experimenter.status_change.set()
                # give thread time to start before presenting template
                time.sleep(1)
        elif request.form['action'] == 'stop':
            experimenter.stop()
            time.sleep(1)

    if os.path.exists(experimenter.dir):
        df = shutil.disk_usage(experimenter.dir)
    else:
        df = shutil.disk_usage(os.path.expanduser('~'))

    diskspace = round(df.free / 1024 ** 3, 1)
    diskreq = round(experimenter.nshots * 4 * 10 / 1024, 1)
    return render_template('experiment.html', running=experimenter.running, directory=experimenter.dir, 
                           starttime=time.ctime(experimenter.starttime), delay=experimenter.delay,
                           endtime=time.ctime(experimenter.endtime), diskspace=diskspace, duration=experimenter.duration,
                           status=experimenter.status, nshots=experimenter.nshots + 1, diskreq=diskreq, name=cfg.get('name'))
Exemple #3
0
def newpass():
    if request.method == 'POST':
        currpass = request.form['currpass']
        pwd1 = request.form['pwd1']
        pwd2 = request.form['pwd2']

        if cfg.get('password') != '':
            if not checkPass(currpass):
                flash("Current password incorrect.")
                return render_template('newpass.html', name=cfg.get('name'))

        if pwd1 == pwd2:
            hash = hashlib.sha1(pwd1.encode('utf-8'))
            cfg.set('password', hash.hexdigest())
            session['password'] = pwd1
            flash("Password was changed.")
            log("Password was changed.")
            return redirect(url_for('index'))
        else:
            flash("Passwords do not match.")
            return redirect(url_for('newpass'))
    else:
        return render_template('newpass.html',
                               nopass=cfg.get('password') == '',
                               name=cfg.get('name'))
Exemple #4
0
def stop_ap():
    log("Disabling services...")
    init()
    config_dhcpcd(enable=False)
    p = subprocess.run(['systemctl', 'restart', 'dhcpcd'], capture_output=True)
    disable_services()
    log("Access point disabled.")
Exemple #5
0
def login():
    if request.method == 'POST':
        pwd = request.form['password']
        if checkPass(pwd):
            session['password'] = pwd
            log("Web user successfully logged in.")
            return redirect(url_for('index'))
        else:
            flash("Incorrect password.")
            log("Incorrect password in web login.")
            return redirect(url_for('login'))
    else:
        return render_template('login.html', name=cfg.get('name'))
Exemple #6
0
def terminate(sig, frame):
    global shutdown
    if sig == signal.SIGALRM:
        # force shutdown
        debug("Shut down time-out, force-quitting.")
        debug("If the software locks up at this point, a reboot is needed.")
        debug("This is due to a bug in the underlying camera code.")
        cam.close()
        sys.exit()

    if not shutdown:
        # give the app 10 seconds to shut down, then force it
        shutdown = True
        signal.alarm(10)

    log("Signal " + str(sig) + " caught -- shutting down.")
    webui.stop()
    hw.motorOn(False)
    cam.close()
    hw.cleanup()
    sys.exit()
Exemple #7
0
    def findStart(self, calibration=None):
        """rotates the imaging stage until the positional switch is activated"""
        calibration = calibration or self.cfg.get('calibration')
        timeout = 60
        starttime = time.time()

        # make sure that switch is not depressed when starting
        if gpio.input(self.pins['sensor']):
            while gpio.input(
                    self.pins['sensor']) and time.time() < starttime + timeout:
                self.halfStep(1, 0.03)

        while not gpio.input(
                self.pins['sensor']) and time.time() < starttime + timeout:
            self.halfStep(1, 0.03)

        if time.time() < starttime + timeout:
            self.halfStep(calibration, 0.03)
        else:
            log("Timed out while finding start position! Images will be misaligned."
                )
Exemple #8
0
 def stop(self):
     self.status = "Stopping"
     self.next_status = ''
     self.stop_experiment = True
     log("Stopping running experiment...")
Exemple #9
0
    def runExperiment(self):
        if self.running:
            raise RuntimeError('An experiment is already running.')

        try:
            debug("Starting experiment.")
            self.running = True
            self.status = "Initiating"
            self.starttime = time.time()
            self.endtime = time.time() + 60 * 60 * 24 * self.duration
            self.last_captured = None
            self.delay = self.delay or 0.001
            self.nshots = self.duration * 24 * 60 // self.delay
            self.cam.exposure_mode = "auto"
            self.cam.shutter_speed = 0
            self.hw.LEDControl(False)

            for i in range(4):
                platedir = "plate" + str(i + 1)
                os.makedirs(os.path.join(self.dir, platedir), exist_ok=True)

            while time.time() < self.endtime and not self.stop_experiment:
                loopstart = time.time()
                nextloop = time.time() + 60 * self.delay
                if nextloop > self.endtime:
                    nextloop = self.endtime

                for i in range(4):
                    # rotate stage to starting position
                    if i == 0:
                        self.hw.motorOn(True)
                        self.status = "Finding start position"
                        debug("Finding initial position.")
                        self.hw.findStart(
                            calibration=self.cfg.get('calibration'))
                        debug("Found initial position.")
                    else:
                        self.status = "Imaging"
                        # rotate cube 90 degrees
                        debug("Rotating stage.")
                        self.hw.halfStep(100, 0.03)

                    # wait for the cube to stabilize
                    time.sleep(0.5)

                    now = time.strftime("%Y%m%d-%H%M%S", time.localtime())
                    name = os.path.join("plate" + str(i + 1),
                                        "plate" + str(i + 1) + "-" + now)
                    self.takePicture(name)

                self.nshots -= 1
                self.hw.motorOn(False)
                self.status = "Waiting"

                if self.idlepos > 0:
                    # alternate between resting positions during idle, stepping 45 degrees per image
                    self.hw.motorOn(True)
                    self.hw.halfStep(50 * self.idlepos, 0.03)
                    self.hw.motorOn(False)

                self.idlepos += 1
                if self.idlepos > 7:
                    self.idlepos = 0

                while time.time() < nextloop and not self.stop_experiment:
                    # keep rotating while waiting, similar light conditions for each plate
                    self.hw.motorOn(True)
                    self.hw.halfStep(21, 0.03)
                    self.hw.motorOn(False)
                    time.sleep(60)

        finally:
            log("Experiment stopped.")
            self.cam.color_effects = None
            self.status = "Stopped"
            self.stop_experiment = False
            self.running = False
            self.cam.exposure_mode = "auto"
            self.cam.meter_mode = 'spot'
Exemple #10
0
    def runExperiment(self):
        if self.running:
            raise RuntimeError('An experiment is already running.')

        try:
            debug("Starting experiment.")
            self.running = True
            self.status = "Initiating"
            self.starttime = time.time()
            self.endtime = time.time() + 60 * 60 * 24 * self.duration
            self.last_captured = None
            self.delay = self.delay or 0.001
            self.nshots = self.duration * 24 * 60 // self.delay
            self.cam.exposure_mode = "auto"
            self.cam.shutter_speed = 0
            self.hw.LEDControl(False)

            for i in range(4):
                platedir = "plate" + str(i + 1)
                os.makedirs(os.path.join(self.dir, platedir), exist_ok=True)

            while time.time() < self.endtime and not self.stop_experiment:
                loopstart = time.time()
                nextloop = time.time() + 60 * self.delay
                if nextloop > self.endtime:
                    nextloop = self.endtime

                for i in range(4):
                    # rotate stage to starting position
                    if i == 0:
                        self.hw.motorOn(True)
                        self.status = "Finding start position"
                        debug("Finding initial position.")
                        self.hw.findStart(
                            calibration=self.cfg.get('calibration'))
                        debug("Found initial position.")
                    else:
                        self.status = "Imaging"
                        # rotate cube 90 degrees
                        debug("Rotating stage.")
                        self.hw.halfStep(100, 0.03)

                    # wait for the cube to stabilize
                    time.sleep(0.5)

                    now = time.strftime("%Y%m%d-%H%M%S", time.localtime())
                    name = os.path.join("plate" + str(i + 1),
                                        "plate" + str(i + 1) + "-" + now)
                    self.takePicture(name)

                self.nshots -= 1
                self.hw.motorOn(False)

                # this part is "active waiting", rotating the cube slowly over the period of options.delay
                # this ensures consistent lighting for all plates.
                # account for the time spent capturing images.
                self.status = "Waiting"
                secs = 0
                while time.time() < nextloop and not self.stop_experiment:
                    time.sleep(1)
                    secs += 1
                    if self.delay > 15 and secs == int(self.delay / 7.5):
                        # don't bother if delay is very short (<= 15 min)
                        secs = 0
                        self.hw.motorOn(True)
                        self.hw.halfStep(50, 0.03)
                        self.hw.motorOn(False)

        finally:
            log("Experiment stopped.")
            self.cam.color_effects = None
            self.status = "Stopped"
            self.stop_experiment = False
            self.running = False
            self.cam.exposure_mode = "auto"
            self.cam.meter_mode = 'spot'
Exemple #11
0
def start_ap():
    log("Setting up dependencies...")
    init()
    install_reqs()
    log("Configuring system...")
    config_dhcpcd(enable=True)
    config_dnsmasq()
    ssid, pwd = config_hostapd()
    log("Starting services...")
    enable_services()
    r = restart_services()
    if not r:
        log("Failed to restart services.")
        log("Setting up access point failed.")
        return (1)
    else:
        log("Access point configured and enabled. Below are the details for connecting to it:"
            )
        log("\nSSID:     " + ssid)
        log("Password: "******"\nConnect to the web interface using the address http://spiro.local"
            )
        return (0)