Example #1
0
class Task(ColorLayer, pyglet.event.EventDispatcher):
    
    d = Dispatcher()
    
    states = ["INIT", "CALIBRATE", "IGNORE_INPUT", "TASK", "DONE"]
    STATE_INIT = 0
    STATE_CALIBRATE = 1
    STATE_IGNORE_INPUT = 2
    STATE_TASK = 3
    STATE_DONE = 4
    
    BG_TILE_SIZE = (1024,128)
    FG_TILE_SIZE = (1024,128)
    
    is_event_handler = True
    
    def __init__(self, client=None):
        self.screen = director.get_window_size()
        super(Task, self).__init__(0, 0, 0, 255, 1024, int(768*1.1))
        self.client = client
        self.state = self.STATE_INIT
        
        self.mole_images = [resource.image('mole_1.png'),
                            resource.image('mole_laugh1.png'),
                            resource.image('mole_laugh2.png'),
                            resource.image('mole_laugh3.png'),
                            resource.image('mole_thump1.png'),
                            resource.image('mole_thump2.png'),
                            resource.image('mole_thump3.png'),
                            resource.image('mole_thump4.png')]
        
        self.music = Player()
        self.music.queue(pyglet.resource.media('whack.mp3'))
        self.music.eos_action = 'loop'
        
        self.cm = CollisionManagerBruteForce()
        
        self.moles = []
        for i in range(0,3):
            mole = Mole(self.mole_images, (112 + (i * 310)), (127-80))
            self.moles.append(mole)
            self.add(mole, 55)
            self.cm.add(mole)
        for i in range(3,6):
            mole = Mole(self.mole_images, (112 + ((i-3) * 310)), (383-80))
            self.moles.append(mole)
            self.add(mole, 35)
            self.cm.add(mole)
        for i in range(6,9):
            mole = Mole(self.mole_images, (112 + ((i-6) * 310)), (639-80))
            self.moles.append(mole)
            self.add(mole, 15)
            self.cm.add(mole)
            
        self.text_batch = BatchNode()
        self.add(self.text_batch, z=100)
        
        self.score = 0
            
        scorey = int((768 + int(768*1.1))/2)
        self.score_num = text.Label("%06d" % self.score, font_name="Score Board", font_size=48, x=512, y=scorey, color=(255, 255, 255, 255),
                                    anchor_x='center', anchor_y='center', batch=self.text_batch.batch)
                                            
        self.fix = Label('G', font_name='Cut Outs for 3D FX', font_size=48,
                          position=(0,0), color=(255, 0, 0, 192), anchor_x='center', anchor_y='center')
        self.fix.visible = False
        self.add(self.fix, z=100000)

        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,0)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,128)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,256)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,384)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,512)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,640)))
        
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,0)), z=60)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,128)), z=50)
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,256)), z=40)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,384)), z=30)
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,512)), z=20)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,640)), z=10)
        
        
    def set_score(self):
        self.score_num.begin_update()
        self.score_num.text = "%06d" % self.score
        self.score_num.end_update()
        
    def visit(self):
        super(Task, self).visit()
        if director.settings["overlay"]:
            for mole in self.moles:
                if mole.opacity > -1:
                    if mole.state == 1:
                        color = (.3,0.0,0.0,.7)
                    else:
                        color = (.3,0.2,0.5,.7)
                    p = Polygon([(mole.center[0]-mole.rx, mole.center[1]-mole.ry), 
                                 (mole.center[0]+mole.rx, mole.center[1]-mole.ry),
                                 (mole.center[0]+mole.rx, mole.center[1]+mole.ry),
                                 (mole.center[0]-mole.rx, mole.center[1]+mole.ry)],
                                color=color)
                    p.render()
        
    def mole_up(self):
        moles = [mole for mole in self.moles if not mole.active]
        if moles:
            random.choice(moles).up()
        
    def animate(self, dt):
        self.mole_up()
        if random.randint(0, 3) == 0:
            self.mole_up()
                    
    def game_over(self):
        self.state = self.STATE_GAME_OVER
        
    def clear(self):
        self.music.pause()
        self.music.seek(0)
        for mole in self.moles:
            mole.active = False
            mole.state = 0
            mole.position = mole.position_in
        pyglet.clock.unschedule(self.animate)
        if self.client:
            self.client.removeDispatcher(self.d)
            self.client.stopDataStreaming()
            self.client.stopFixationProcessing()
        
    def reset(self):
        self.clear()
        if self.client:
            self.client.addDispatcher(self.d)
            #self.client.setDataFormat('%TS %ET %SX %SY %DX %DY %EX %EY %EZ')
            #self.client.startDataStreaming()
            self.client.startFixationProcessing()
        self.state = self.STATE_TASK
        self.score = 0
        pyglet.clock.schedule_interval(self.animate, .5)
        self.music.play()
        
    def on_enter(self):
        if isinstance(director.scene, TransitionScene): return
        super(Task, self).on_enter()
        
        if director.settings['eyetracker']:
            self.state = self.STATE_CALIBRATE
            self.dispatch_event("start_calibration", self.calibration_ok, self.calibration_bad)
        else:
            self.reset()
            
    def calibration_ok(self):
        self.dispatch_event("stop_calibration")
        self.reset()
        
    def calibration_bad(self):
        self.dispatch_event("stop_calibration")
        director.scene.dispatch_event("show_intro_scene")
        
    def on_exit(self):
        if isinstance(director.scene, TransitionScene): return
        super(Task, self).on_exit()
        self.clear()

    @d.listen('ET_FIX')
    def iViewXEvent(self, inResponse):
        if inResponse[0] == 'l':
            x = int(float(inResponse[2]))
            y = int(float(inResponse[3]))
            if director.settings["overlay"]:
                self.fix.position = (x, y)
                self.fix.visible = True
            self.handle_mouse_press(x, y)
    
    @d.listen('ET_EFX')
    def iViewXEvent(self, inResponse):
        if inResponse[0] == 'l':
            if director.settings["overlay"]:
                self.fix.visible = False
    
    @d.listen('ET_SPL')
    def iViewXEvent(self, inResponse):
        pass
        
    def handle_mouse_press(self, x, y):
        for obj in self.cm.objs_touching_point(x, y):
            if obj.active:
                if obj.state == 0:
                    obj.state = 1
                    obj.thump()
                    self.score += 10
                elif obj.state == 2:
                    self.score -= 10
                self.set_score()
        
    def on_mouse_press(self, x, y, buttons, modifiers):
        posx, posy = director.get_virtual_coordinates(x, y)
        self.handle_mouse_press(posx, posy)

    def on_mouse_motion(self, x, y, dx, dy):
        pass
        
    def on_key_press(self, symbol, modifiers):
        if self.state < self.STATE_IGNORE_INPUT: return
        if symbol == key.W and (modifiers & key.MOD_ACCEL):
            director.scene.dispatch_event("show_intro_scene")
            True
        if self.state == self.STATE_TASK:
            pass
        elif self.state == self.STATE_DONE:
            pass
Example #2
0
class SoundPlayer(object):
    def __init__(self, soundDirPath):
        self.soundDirPath = soundDirPath
        self.loadSounds()
        self.musicPlayer = Player()
        self.queue = False
        self.queuePlayer = None
        self.enabled = True
        self.soundEffectVolume = 1.0  # between 0.0 and 1.0
        self._musicVolume = 1.0  # between 0.0 and 1.0

    '''
        loads sounds from gui config file into dict.
        maps name to pyglet sound object.
        if ',stream' exists after filename in config file,
         will stream file instead of loading the whole thing in once.
    '''

    def loadSounds(self):
        self.sounds = dict()
        soundTypes = dict(gui.config.items('sound_events'))
        for key in soundTypes:
            self._loadSoundResource(key)

    @staticmethod
    def _loadSoundEntry(key):
        entry = gui.config.get('sound_events', key)
        if ',' in entry:
            sp = entry.split(",")
            fileName = sp[0]
            if sp[1] == "stream":
                stream = True
        else:
            fileName = entry
            stream = False
        return fileName, stream

    def _loadSoundResource(self, key):
        fileName, stream = self._loadSoundEntry(key)
        if key in self.sounds:
            self.sounds[key].delete()
        self.sounds[key] = pyglet.resource.media(self.soundDirPath + fileName,
                                                 streaming=stream)

    def shutdown(self):
        from pyglet.media import avbin
        if self.musicPlayer.source is not None:
            avbin.av.avbin_close_file(
                self.musicPlayer.source._file
            )  # hack to ensure avbin closes properly.
        self.musicPlayer.delete()
        toDel = self.sounds.keys()
        for snd in toDel:
            del self.sounds[snd]

    @property
    def musicVolume(self):
        return self._soundEffectVolume

    @musicVolume.setter
    def musicVolume(self, value):
        self.musicPlayer.volume = value
        self._musicVolume = self.musicPlayer.volume

    def setMute(self, value):
        self.enabled = value

    def getSound(self, soundName):
        try:
            snd = self.sounds[soundName.lower()]
        except KeyError:
            print "Sound requsted to be played does not exist in config file."
            return None
        return snd

    def playMusic(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        if self.musicPlayer.playing and self.musicPlayer.source == snd:
            self.musicPlayer.seek(0)
            return
        else:
            # reload sound and reset Player obj
            # (streaming sounds needs to be reloaded every time)
            if isinstance(snd, pyglet.media.StreamingSource):
                self._loadSoundResource(soundName)
            self.musicPlayer.delete()
            self.musicPlayer = Player()
            self.musicPlayer.volume = self._musicVolume
        looper = pyglet.media.SourceGroup(snd.audio_format, None)
        looper.loop = True
        looper.queue(snd)
        self.musicPlayer.queue(looper)
        self.musicPlayer.play()

    def playEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        p = Player()
        p.volume = self.soundEffectVolume
        p.queue(snd)
        p.play()

    def startEffectsQueue(self):
        self.queue = True
        self.queuePlayer = Player()

    def queueEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        self.queuePlayer.queue(snd)

    '''
        Plays the queue and resets queue state.
    '''

    def playEffectsQueue(self):
        self.queuePlayer.volume = self.soundEffectVolume
        self.queuePlayer.play()
        self.queue = False
        self.queuePlayer = None
Example #3
0
class Gui(object):
    def __init__(self, manager, win, debug=False):
        self.manager = manager
        self.debug = debug
        #self.lab=Label(win, text="Serial port:")
        #self.lab.place(x=30, y=20)
        #self.txtfld=Entry(win, text="Serial port")
        #self.txtfld.place(x=300, y=20)
        #self.btn_cnct=Button(win, text="Connect printer", command=self.connect)
        #self.btn_cnct.place(x=30, y=50)
        #self.btn_init=Button(win, text="Initialize", command=self.initialize, state=DISABLED)
        #self.btn_init.place(x=30, y=90)

        #self.tidal_vol=("300","400","500","750","900","1000")
        #self.lab_tv=Label(win, text='Tidal volume:')
        #self.lab_tv.place(x=30, y=180)
        #self.tv=Combobox(win, values=self.tidal_vol)
        #self.tv.place(x=240, y=180)

        #self.resp_rate=("12","16","20","32")
        #self.lab_rr=Label(win, text='Respiratory rate:')
        #self.lab_rr.place(x=30, y=210)
        #self.rr=Combobox(win, values=self.resp_rate)
        #self.rr.place(x=240, y=210)

        #self.insp_exp=("1:2")
        #self.lab_ie=Label(win, text='Inspiratory/expiratory:')
        #self.lab_ie.place(x=30, y=240)
        #self.ie=Combobox(win, values=self.insp_exp)
        #self.ie.place(x=240, y=240)

        #self.btn_run=Button(win, text="Run Ventilation", command=self.start_run,state=DISABLED)
        #self.btn_run.place(x=30, y=310)
        #self.btn_stop=Button(win, text="Stop",command=self.stop,state=DISABLED)
        #self.btn_stop.place(x=180, y=310)

        self.readings = []
        self.state = None

        self.reading_pressure = Label(win,
                                      text="Latest pressure (cmH2O)",
                                      font=("Helvetica", 18))
        self.reading_pressure.place(x=30, y=20)
        self.reading_ppeak = Label(win,
                                   text="Latest PPeak (cmH2O)",
                                   font=("Helvetica", 18))
        self.reading_ppeak.place(x=35, y=50)
        self.reading_timestamp = Label(win,
                                       text="Latest reading age (seconds)")
        self.reading_timestamp.place(x=30, y=90)
        self.reading_sample_rate = Label(win, text="Sample Rate")
        self.reading_sample_rate.place(x=30, y=110)
        self.reading_pressure_inches = Label(win,
                                             text="Latest pressure (inH2O)")
        self.reading_pressure_inches.place(x=30, y=130)
        self.exit_button = Button(win,
                                  text="Close App",
                                  command=self.exit_application)
        self.exit_button.place(x=460, y=1)

        Thread(target=self.timestampDisplayThread, args=[]).start()

        self.pressure_options = [i for i in range(0, PRESSURE_UPPER_LIMIT + 1)]
        self.max_alarm_enabled = BooleanVar(False)
        self.min_alarm_enabled = BooleanVar(False)
        self.timeout_alarm_enabled = BooleanVar(False)
        self.timeout_alarm_enabled.set(True)

        self.min_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Min Pressure Alarm", self.min_alarm_enabled)
        self.min_alarm_enabled_checkbox.place(x=30, y=160)
        self.min_alarm_threshold_label = Label(win,
                                               text="Minimum Pressure (cmH2O)")
        self.min_alarm_threshold_label.place(x=30, y=220)
        self.min_alarm_threshold_input = Combobox(win,
                                                  values=self.pressure_options)
        self.min_alarm_threshold_input.current(0)
        self.min_alarm_threshold_input.place(x=30, y=240)
        self.min_alarm_interval_label = Label(win,
                                              text="Alarm Interval (seconds)")
        self.min_alarm_interval_label.place(x=30, y=265)
        self.min_alarm_interval_input = Combobox(win, values=INTERVAL_LABELS)
        self.min_alarm_interval_input.current(0)
        self.min_alarm_interval_input.place(x=30, y=285)

        self.max_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Max Pressure Alarm", self.max_alarm_enabled)
        self.max_alarm_enabled_checkbox.place(x=280, y=160)
        self.max_alarm_threshold_label = Label(win,
                                               text="Maximum Pressure (cmH2O)")
        self.max_alarm_threshold_label.place(x=280, y=220)
        self.max_alarm_threshold_input = Combobox(win,
                                                  values=self.pressure_options)
        self.max_alarm_threshold_input.current(len(self.pressure_options) - 31)
        self.max_alarm_threshold_input.place(x=280, y=240)
        self.max_alarm_interval_label = Label(win,
                                              text="Alarm Interval (seconds)")
        self.max_alarm_interval_label.place(x=280, y=265)
        self.max_alarm_interval_input = Combobox(win, values=INTERVAL_LABELS)
        self.max_alarm_interval_input.current(0)
        self.max_alarm_interval_input.place(x=280, y=285)

        self.timeout_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Lost Signal Alarm", self.timeout_alarm_enabled)
        self.timeout_alarm_enabled_checkbox.place(x=30, y=320)
        self.timeout_alarm_interval_label = Label(
            win, text="Lost Signal Timeout (seconds)")
        self.timeout_alarm_interval_label.place(x=30, y=380)
        self.timeout_alarm_interval_input = Combobox(win,
                                                     values=TIMEOUT_LABELS)
        self.timeout_alarm_interval_input.current(0)
        self.timeout_alarm_interval_input.place(x=30, y=400)

        self.test_alarm = Button(win,
                                 text="Test Alarm",
                                 command=self.test_alarm)
        self.test_alarm.place(x=285, y=365)
        self.clear_alarm = Button(win,
                                  text="Clear Alarm",
                                  command=self.clear_alarm)
        self.clear_alarm.place(x=285, y=395)

        self.alarm_active = False
        self.alarm_messages = []
        self.alarms_messages_var = StringVar()
        self.alarms_messages_label = Label(
            win, textvariable=self.alarms_messages_var, font=("Helvetica", 32))
        self.alarms_messages_label.place(x=30, y=440)
        self.alarms_messages_label['bg'] = 'lightgrey'
        self.alarms_messages_label['fg'] = 'red'

        self.player = None
        self.last_seek = datetime.now()
        Thread(target=self.pygletThread, args=[]).start()
        Thread(target=self.alarmThread, args=[]).start()

        #TODO
        #self.place_dropdown(win,'Tidal volume:', self.tidal_vol, 60, 180)
        #self.place_dropdown(win,'Respiratory rate:', self.resp_rate, 60, 210)
        #self.place_dropdown(win,'Inspiratory/expiratory:', self.insp_exp, 60, 240)
        #self.place_btn(win,"Run ventilation", self.run,60,290)
        #self.place_btn(win,"Stop", self.run,180,290)

        #3dpav control
        self.printer = None
        self.lookup = None
        self.started_run = False
        self._isOk = False

        self.window = win

    def exit_application(self):
        self.manager.shutdown()

    def shutdown(self):
        self.window.destroy()

    def boot(self):
        self.window.title('3DPaV Pressure Monitor')
        self.window.geometry("529x564+0+0")
        self.window.mainloop()

    def pygletThread(self):
        self.player = Player()
        source = pyglet.resource.media('red_alert.wav')
        self.player.queue(source)
        pyglet.app.run()

    def timestampDisplayThread(self):
        while True:
            self.ui_updater_func()
            time.sleep(0.01)

    def test_alarm(self):
        self.add_alarm("Test Alarm")

    def clear_alarm(self):
        self.alarm_active = False
        self.alarm_messages = []
        self.alarms_messages_label['bg'] = 'lightgrey'
        self.window['bg'] = 'lightgrey'

    def add_alarm(self, alarm_message):
        self.alarm_active = True
        self.alarm_messages = list(set(self.alarm_messages + [alarm_message]))
        self.alarms_messages_label['bg'] = 'white'
        self.window['bg'] = 'red'

    def alarmThread(self):
        while True:
            now = datetime.now()
            if ((now - self.last_seek).total_seconds() > LOOP_TIMEOUT_SECONDS):
                self.player.seek(0)
                self.last_seek = now
            if (self.player):
                if (self.alarm_active):
                    if not self.player.playing:
                        print('START ALERT')
                        self.player.play()
                else:
                    if self.player.playing:
                        print('STOP ALERT')
                        self.player.pause()
            time.sleep(0.01)

    def updateReadings(self, state):
        self.readings.append(
            Reading(state['latestPressureValue'], state['timestamp']))
        self.state = state

    def ui_updater_func(self):
        state = self.state
        if state is None:
            return
        timestamp = state['timestamp']
        latestPressureValue = state['latestPressureValue']
        latestPPeakValue = state['latestPPeakValue']
        sampleRate = state['sampleRate']

        self.reading_pressure.configure(
            text="Latest Pressure (cmH2O): {:10.2f}".format(
                latestPressureValue))
        self.reading_pressure_inches.configure(
            text="Latest Pressure (inH2O): {:10.2f}".format(
                latestPressureValue / INCHES_TO_CENIMETERS))
        self.reading_ppeak.configure(
            text="Latest PPeak (cmH2O):    {:10.2f}".format(latestPPeakValue))
        self.reading_sample_rate.configure(
            text="Sample Rate (ms): {:10.2f}".format(sampleRate * 1000))
        self.alarms_messages_var.set(", \n".join(self.alarm_messages))

        now = datetime.now()
        min_alarm_label = self.min_alarm_interval_input.get()
        max_alarm_label = self.max_alarm_interval_input.get()
        min_alarm_interval = INTERVAL_OPTIONS_MAP[min_alarm_label]
        max_alarm_interval = INTERVAL_OPTIONS_MAP[max_alarm_label]
        self.readings = [
            r for r in self.readings
            if ((now - r.stamp).total_seconds() < (2 * MAX_INTERVAL_VALUE))
        ]

        trigger_max_alert = False
        if (self.max_alarm_enabled.get()):
            max_samples = [
                r for r in self.readings
                if ((now - r.stamp).total_seconds() < max_alarm_interval)
            ]
            max_threshold = int(self.max_alarm_threshold_input.get())
            if max_alarm_label == IMMEDIATE_KEY_WORD:
                trigger_max_alert = len(
                    [r for r in max_samples if r.value >= max_threshold]) > 0
            elif (len(max_samples) < len(self.readings)):
                trigger_max_alert = len(
                    [r for r in max_samples if r.value < max_threshold]) == 0

        trigger_min_alert = False
        if (self.min_alarm_enabled.get()):
            min_samples = [
                r for r in self.readings
                if ((now - r.stamp).total_seconds() < min_alarm_interval)
            ]
            min_threshold = int(self.min_alarm_threshold_input.get())
            if min_alarm_label == IMMEDIATE_KEY_WORD:
                trigger_min_alert = len(
                    [r for r in min_samples if r.value <= min_threshold]) > 0
            elif (len(min_samples) < len(self.readings)):
                trigger_min_alert = len(
                    [r for r in min_samples if r.value > min_threshold]) == 0

        if trigger_min_alert:
            self.add_alarm("Min Pressure Alarm")
        if trigger_max_alert:
            self.add_alarm("Max Pressure Alarm")

        if timestamp is not None:
            delta_seconds = (datetime.now() - timestamp).total_seconds()
            self.reading_timestamp.configure(
                text="Latest reading: {:10.2f} seconds ago".format(
                    delta_seconds))
            if (self.timeout_alarm_enabled.get()):
                timeout_threshold = TIMEOUT_OPTIONS_MAP[
                    self.timeout_alarm_interval_input.get()]
                if delta_seconds > timeout_threshold:
                    self.add_alarm("Signal Lost")

    @property
    def isOk(self):
        return self._isOk

    @isOk.setter
    def isOk(self, new_value):
        if self.debug: print('isOk being updated to ' + str(new_value))
        self._isOk = new_value
        if self.started_run and new_value == True:
            if self.debug: print('adding another run with ' + str(self.lookup))
            g_run(self, self.lookup, self.debug)
            #deprecated? keep it all on one thread for now
            #t = Thread(target = g_run, args =(self,self.lookup,self.debug ))

    #------------------------- aesthetics
    def place_dropdown(self, win, txt, vals, xstart=60, ystart=180):
        self.lab = Label(win, text=txt)
        self.lab.place(x=xstart, y=ystart)
        self.box = Combobox(win, values=vals)
        self.box.place(x=xstart + 160, y=ystart)

    def place_btn(self, win, txt, cmd, xstart=60, ystart=180):
        self.btn = Button(win, text=txt, command=cmd)
        self.btn.place(x=xstart, y=ystart)

    #-------------------------- ventilator methods
    def connect(self):
        if self.txtfld.get() == '':
            path = '/Users/juliagonski/Documents/Columbia/3DprinterAsVentilator/pronsoleWork/Printator/sim'
        else:
            path = self.txtfld.get()
        ser_printer = serial.Serial(path, baudRate)

        print("Connecting to printer...")
        time.sleep(1)  # Allow time for response
        if self.debug:
            print("Connection response from printer:",
                  ser_printer.read(ser_printer.inWaiting()))
        #ser_printer.write(str.encode('M400\n'))
        #ser_printer.write(str.encode('M400\n'))
        answer = ser_printer.readline()

        if 'ok' in answer.decode("utf-8", "ignore"):
            print("------ Done connecting!")
            print("")
        self.printer = ser_printer
        self.btn_init["state"] = "normal"

    def initialize(self):
        g_init(self, self.debug)
        self.btn_run["state"] = "normal"

    #def check_run(self, win):
    #  if self.started_run == 1:
    #    answer = self.waitForOk(self.printer)
    #    if self.debug: print("waiting response from printer?", answer)
    #    if 'ok' in answer.decode("utf-8", "ignore"): g_run(self,self.debug)
    #    #else: print('not ventilating, not adding more runs')
    #  win.after(2000,self.check_run,win)

    def start_run(self):
        self.printer.flush()
        self.started_run = True
        sel_tv = self.tv.get()
        sel_rr = self.rr.get()
        sel_ie = self.ie.get()
        self.lookup = sel_tv + "mL_" + sel_rr + "BPM_" + sel_ie
        print('Started new protocol: ' + str(self.lookup))
        self.btn_stop["state"] = "normal"
        #Start first thread, join subsequent ones
        t_orig = Thread(target=g_run, args=(self, self.lookup, self.debug))
        t_orig.start()

    def stop(self):
        self.started_run = False
        self.printer.flush()
        g_stop(self, self.debug)

    def waitForOk(self, ser_printer):
        if self.debug: print('BEGIN waitForOk')
        isItOk = False
        answer = ''
        quantity = ser_printer.inWaiting()
        while True:
            if quantity > 0:
                #answer += ser_printer.read(quantity)
                answer += ser_printer.read(quantity).decode("utf-8", "ignore")
                ##if 'ok' in answer.decode("utf-8", "ignore"):
                if 'ok' in answer:
                    if self.debug: print('found ok, breaking')
                    isItOk = True
                    break
            else:
                time.sleep(read_timeout)
            quantity = ser_printer.inWaiting()
            #if quantity == 0:
            #if self.debug: print('-------> No lines to read out')
            #print('ERROR connecting!!!')
            #raise ImportError()
            #break
        if self.debug: print('resulting answer: ', answer)
        return isItOk

    def waitForDONE(self, ser_printer):
        if self.debug: print('----- BEGIN waitForDONE')
        isItOk = False
        answer = ''
        quantity = ser_printer.inWaiting()
        while True:
            if quantity > 0:
                if self.debug:
                    print('----- reading what the printer has to say: ',
                          ser_printer.read(quantity).decode("utf-8", "ignore"))
                answer += ser_printer.read(quantity).decode("utf-8", "ignore")
                #deprecated new firmware 0622 if 'ok' in answer:
                if 'DECOMPRESSDONE' in answer:
                    if self.debug:
                        print('----- found DECMOMPRESSDONE in answer')
                    isItOk = True
                    break
            else:
                time.sleep(read_timeout)
            quantity = ser_printer.inWaiting()
            #if quantity == 0:
            #if self.debug: print('-------> No lines to read out')
            #print('ERROR connecting!!!')
            #raise ImportError()
            #break
        if self.debug:
            print(
                '----- resulting answer of concatented printer output (should end in DECOMPRESSDONE): ',
                answer)
        return isItOk
Example #4
0
class SoundPlayer(object):
    def __init__(self, soundDirPath):
        self.soundDirPath = soundDirPath
        self.loadSounds()
        self.musicPlayer = Player()
        self.queue = False
        self.queuePlayer = None
        self.enabled = True
        self.soundEffectVolume = 1.0  # between 0.0 and 1.0
        self._musicVolume = 1.0  # between 0.0 and 1.0

    """
        loads sounds from gui config file into dict.
        maps name to pyglet sound object.
        if ',stream' exists after filename in config file,
         will stream file instead of loading the whole thing in once.
    """

    def loadSounds(self):
        self.sounds = dict()
        soundTypes = dict(gui.config.items("sound_events"))
        for key in soundTypes:
            self._loadSoundResource(key)

    @staticmethod
    def _loadSoundEntry(key):
        entry = gui.config.get("sound_events", key)
        if "," in entry:
            sp = entry.split(",")
            fileName = sp[0]
            if sp[1] == "stream":
                stream = True
        else:
            fileName = entry
            stream = False
        return fileName, stream

    def _loadSoundResource(self, key):
        fileName, stream = self._loadSoundEntry(key)
        if key in self.sounds:
            self.sounds[key].delete()
        self.sounds[key] = pyglet.resource.media(self.soundDirPath + fileName, streaming=stream)

    def shutdown(self):
        from pyglet.media import avbin

        if self.musicPlayer.source is not None:
            avbin.av.avbin_close_file(self.musicPlayer.source._file)  # hack to ensure avbin closes properly.
        self.musicPlayer.delete()
        toDel = self.sounds.keys()
        for snd in toDel:
            del self.sounds[snd]

    @property
    def musicVolume(self):
        return self._soundEffectVolume

    @musicVolume.setter
    def musicVolume(self, value):
        self.musicPlayer.volume = value
        self._musicVolume = self.musicPlayer.volume

    def setMute(self, value):
        self.enabled = value

    def getSound(self, soundName):
        try:
            snd = self.sounds[soundName.lower()]
        except KeyError:
            print "Sound requsted to be played does not exist in config file."
            return None
        return snd

    def playMusic(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        if self.musicPlayer.playing and self.musicPlayer.source == snd:
            self.musicPlayer.seek(0)
            return
        else:
            # reload sound and reset Player obj
            # (streaming sounds needs to be reloaded every time)
            if isinstance(snd, pyglet.media.StreamingSource):
                self._loadSoundResource(soundName)
            self.musicPlayer.delete()
            self.musicPlayer = Player()
            self.musicPlayer.volume = self._musicVolume
        looper = pyglet.media.SourceGroup(snd.audio_format, None)
        looper.loop = True
        looper.queue(snd)
        self.musicPlayer.queue(looper)
        self.musicPlayer.play()

    def playEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        p = Player()
        p.volume = self.soundEffectVolume
        p.queue(snd)
        p.play()

    def startEffectsQueue(self):
        self.queue = True
        self.queuePlayer = Player()

    def queueEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        self.queuePlayer.queue(snd)

    """
        Plays the queue and resets queue state.
    """

    def playEffectsQueue(self):
        self.queuePlayer.volume = self.soundEffectVolume
        self.queuePlayer.play()
        self.queue = False
        self.queuePlayer = None