예제 #1
0
    def add_widgets(self):
        # Tabbed view
        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill=tk.BOTH, expand=1)
        self.notebook.bind("<<NotebookTabChanged>>", self.manage_threads)

        # First Tab: Alarms
        self.alarms = Alarms(self.notebook)
        self.protocol("WM_DELETE_WINDOW", self.on_close)
        self.alarms.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.alarms, text="Alarms")

        # Second Tab: Clock (Hopefully will add analog and digital)
        self.clock = Clock(self.notebook)
        self.clock.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.clock, text="Clock")

        # Third Tab: Stopwatch
        self.stopwatch = Stopwatch(self.notebook)
        self.stopwatch.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.stopwatch, text="Stopwatch")

        # Fourth Tab: Timer
        self.timer = Timer(self.notebook)
        self.timer.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.timer, text="Timer")
    def _setup_ui(self):
        self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        layout.setAlignment(Qt.AlignTop)
        layout.setSpacing(2)
        layout.setMargin(2)
        layout.addSpacing(20)

        self._alarms = Alarms(self, self._usbif)
        layout.addWidget(self._alarms)

        self._meas = Measurements(self, self._usbif)
        layout.addWidget(self._meas)

        self._core_rope_sim = CoreRopeSim(self, self._usbif)
        layout.addWidget(self._core_rope_sim)
        layout.setAlignment(self._core_rope_sim, Qt.AlignTop)

        self._erasable_mem_sim = ErasableMemSim(self, self._usbif)
        layout.addWidget(self._erasable_mem_sim)
        layout.setAlignment(self._erasable_mem_sim, Qt.AlignTop)

        self._trace = Trace(self, self._usbif)
        layout.addWidget(self._trace)
예제 #3
0
    def __init__(self):
        """Constructor, esto es lo que se ejecuta cuando se crea un objeto de la clase FaceDetection."""

        self.frame = None
        self.counter = 0
        self.EYE_AR_THRESH = 0.15
        self.EYE_AR_CONSEC_FRAMES = 2
        self.YAWN_THRESH = 10
        self.face_detected = False
        self.yawn_counter = 0
        self.CAR_REGISTRATION = 'SAF 6245'

        self.blink_verification = False
        self.blink_counter = 0
        self.t_end_blink = 0  #Variable para controlar alarma cuando los ojos se cierran
        self.BLINK_TIME_CLOSED = 1  # Tiempo en segundos para que se considere un parpadeo largo
        self.BLINK_TIME_GAP = 60  # el tiempo por el cuazl quedan guardado los parpadeos largos en el array
        self.BLINK_TIME_ALERT = 2  # cantidad de veces que se produscan pestaneos largos antes de que se dispare una alerta
        self.blink_time_alert_counter_a = [
        ]  # se guardan los moentos en que se detectaron los parpadeos largos
        self.blink_counter_verification = False  #veriable que permite verificar el momento de trasiciondes de estado del ojo(de abierto a cerrado)
        self.blink_eye_closed = 0  # momento en el que se detecto que el ojo se cerro

        self.yawn_closed = 0
        self.yawn_counter_verification = False
        self.t_end = 0  #Variable para controlar el tiempo de un bostezo
        self.YAWN_TIME_GAP = 60  #
        self.YAWN_TIME_ALERT = 2  # Cantidad de bostetzos por minuto para que se active la alarma
        self.yawn_time_alert_counter_a = [
        ]  #se guardan los bostezos (se guarda en formato time)
        self.t_end_alarm = 0
        self.EVENT_STRING_DROWSINESS = 'Sintomas de suenio'
        self.EVENT_STRING_SLEEP = 'Dormido'
        self.EVENT_STRING_DISTRACTION = 'Distraccion'
        self.face_angle_vertical = 0.0
        self.face_angle_horizontal = 0.0
        self.face_angle_horizontal = 0.0
        self.alarm = Alarms()

        #_face_detector detecta rostros
        self._face_detector = dlib.get_frontal_face_detector()

        #_predictor es usado para obtener los landmarks de una cara
        self._predictor = dlib.shape_predictor(
            path + "/shape_predictor_68_face_landmarks.dat")
예제 #4
0
파일: talk.py 프로젝트: zetof/VERT-X
    def __init__(self, loggerName, locale, wsURL, wsUser, wsPwd, callback):

        # Initialisation du logging
        logging.config.fileConfig('logging.conf')
        self.logger = logging.getLogger(loggerName)

        # Initialisation du langage
        self.i18n = I18N(locale)

        # Liste des alarmes en cours
        self.alarms = Alarms()

        # Initialisation du panneau des alarmes
        self.alarmPanel = AlarmPanel(8, 7, 11, 9, 600, True)

        # Initialisation de l'écran LCD
        self.lcd = LCDDisplay(27, 22, 25, 24, 23, 18, 16, 2, 4)

        # Liste des Arduinos à contacter
        self.arduinos = []

        # Démarrage du serveur de commande et de la communication vers internet
        self.httpServices = HttpServices(wsURL, wsUser, wsPwd, callback)
예제 #5
0
def deamon(soc=-1):
    """ Main loop, gets battery data, gets summary.py to do logging"""

    try:
        import summary
        logsummary = summary.Summary()
        summary = logsummary.summary
        printtime = time.strftime("%Y%m%d%H%M%S ", time.localtime())
        while int(printtime) <= int(summary['current']['timestamp']):
            print(printtime, summary['current']['timestamp'])
            print("Error: Current time before last sample time")
            time.sleep(30)
            printtime = time.strftime("%Y%m%d%H%M%S", time.localtime())
        batdata = Readings()  # initialise batdata after we have valid sys time
        alarms = Alarms(batdata)  # initialise alarms

        print(str(printtime))
        filecopy(config['files']['summaryfile'],
                 config['files']['summaryfile'] + "R" + str(int(printtime)))
        if soc > config['battery']['capacity']:
            print("Battery DOD must be less than Battery Capacity")

        else:
            if soc < 0:
                batdata.soc = summary['current']['ah'][0]
                batdata.socadj = summary['current']['dod'][0]
            else:
                batdata.soc = soc
                batdata.socadj = soc
                summary['current']['dod'][3] = 0
            summary['current']['dod'][
                3] = -100  # flag don't adjust leakage current
            prevtime = logsummary.currenttime
            prevbatvoltage = batdata.batvoltsav[numcells]
            #    logsummary.startday(summary)
            #    logsummary.starthour(summary)

            while True:
                try:
                    for i in range(config['sampling']['samplesav']):
                        #          printvoltage = ''
                        #          for i in range(numcells+1):
                        #            printvoltage = printvoltage + str(round(batdata.batvolts[i],3)).ljust(5,'0') + ' '
                        #         print (printvoltage)
                        batdata.getraw()

                        #          if batdata.batvoltsav[numcells] >= 55.2 and prevbatvoltage < 55.2:  # reset SOC counter?
                        #          print batdata.socadj/(float(summary['current']['dod'][3])*24.0)
                        if batdata.batvoltsav[numcells] < config['battery']['vreset'] \
                        and prevbatvoltage >= config['battery']['vreset'] \
                        and summary['current']['dod'][3] != 0 \
                        and -batdata.currentav[0] < config['battery']['ireset']:  # reset SOC counter?

                            if summary['current']['dod'][3] <= 0:
                                socerr = 0
                            else:
                                socerr = batdata.socadj / (
                                    float(summary['current']['dod'][3]) * 24.0)
                                socerr = max(socerr, -0.01)
                                socerr = min(socerr, 0.01)
                            config['battery']['ahloss'] = config['battery'][
                                'ahloss'] - socerr / 2
                            batconfigdata = SafeConfigParser()
                            batconfigdata.read('battery.cfg')
                            batconfigdata.set('battery', 'ahloss',
                                              str(config['battery']['ahloss']))
                            with open('battery.cfg', 'w') as batconfig:
                                batconfigdata.write(batconfig)
                            batconfig.closed

                            batdata.soc = 0.0
                            batdata.socadj = 0.0
                            summary['current']['dod'][3] = 0
                        else:
                            batdata.soc = batdata.soc + batdata.batah
                            batdata.socadj = batdata.socadj + batdata.batahadj
                        batdata.ah = batdata.ah + batdata.batah
                        batdata.inahtot = batdata.inahtot + batdata.inah
                        batdata.pwrbattot = batdata.pwrbattot + batdata.pwrbat
                        batdata.pwrintot = batdata.pwrintot + batdata.pwrin
                    prevbatvoltage = batdata.batvoltsav[numcells]
                    # check alarms
                    alarms.scanalarms(batdata)
                    # update summaries
                    logsummary.update(summary, batdata)
                    if logsummary.currenttime[4] != logsummary.prevtime[
                            4]:  # new minute
                        loadconfig()
                        logsummary.updatesection(summary, 'hour', 'current')
                        logsummary.updatesection(summary, 'alltime', 'current')
                        logsummary.updatesection(summary, 'currentday',
                                                 'current')
                        logsummary.updatesection(summary, 'monthtodate',
                                                 'current')
                        logsummary.updatesection(summary, 'yeartodate',
                                                 'current')
                        logsummary.writesummary()
                        batdata.ah = 0.0
                        batdata.ahadj = 0.0
                        batdata.inahtot = 0.0
                        batdata.pwrbattot = 0.0
                        batdata.pwrintot = 0.0
                        for i in range(batdata.numiins):
                            batdata.kWhin[i] = 0.0
                            batdata.kWhout[i] = 0.0
                        for i in range(numcells):
                            batdata.baltime[i] = 0

                    if logsummary.currenttime[3] != logsummary.prevtime[
                            3]:  # new hour
                        logsummary.starthour(summary)

                    if logsummary.currenttime[3] < logsummary.prevtime[
                            3]:  # newday
                        logsummary.startday(summary)

                    if logsummary.currenttime[1] != logsummary.prevtime[
                            1]:  # new month
                        logsummary.startmonth(summary)

                    if logsummary.currenttime[0] != logsummary.prevtime[
                            0]:  # new year
                        logsummary.startyear(summary)

                except KeyboardInterrupt:
                    sys.stdout.write('\n')
                    logsummary.close()
                    sys.exit(9)
                    break
    except Exception as err:
        log.critical(err)
        raise
예제 #6
0
def deamon(soc=-1):
  """ Main loop, gets battery data, gets summary.py to do logging"""
  try:
    import summary
    logsummary = summary.Summary()
    summary = logsummary.summary
    printtime = time.strftime("%Y%m%d%H%M%S ", time.localtime())
    while int(printtime) <= int(summary['current']['timestamp']):
      print(printtime,summary['current']['timestamp'])
      print ("Error: Current time before last sample time")
      time.sleep(30)
      printtime = time.strftime("%Y%m%d%H%M%S", time.localtime())
    batdata = Readings()  # initialise batdata after we have valid sys time
    alarms = Alarms(batdata,summary) # initialise alarms

    print (str(printtime))
    filecopy(config['files']['summaryfile'],config['files']['summaryfile']+"R" + str(int(printtime)))
    if soc > config['battery']['capacity']:
      print ("Battery DOD must be less than Battery Capacity")

    else:
      if soc < 0:
         batdata.soc = summary['current']['ah'][0]
         batdata.socadj = summary['current']['dod'][0]
      else:
        batdata.soc = soc
        batdata.socadj = soc
        summary['current']['dod'][3] = 0
      summary['current']['dod'][3] = -100 # flag don't adjust leakage current
      prevtime = logsummary.currenttime
      prevbatvoltage = batdata.batvoltsav[numcells]
  #    logsummary.startday(summary)
  #    logsummary.starthour(summary)


      while True:
        try:
          for i in range(config['sampling']['samplesav']):
  #          printvoltage = ''
  #          for i in range(numcells+1):
  #            printvoltage = printvoltage + str(round(batdata.batvolts[i],3)).ljust(5,'0') + ' '
  #         print (printvoltage)
            batdata.getraw()

  #          if batdata.batvoltsav[numcells] >= 55.2 and prevbatvoltage < 55.2:  # reset SOC counter?
  #          print batdata.socadj/(float(summary['current']['dod'][3])*24.0)
            if batdata.batvoltsav[numcells] < config['battery']['vreset'] \
            and prevbatvoltage >= config['battery']['vreset'] \
            and summary['current']['dod'][3] != 0 \
            and -batdata.currentav[0] < config['battery']['ireset']:  # reset SOC counter?

              if summary['current']['dod'][3] <= 0 :
                socerr=0
              else:
                socerr=batdata.socadj/(float(summary['current']['dod'][3])*24.0)
                socerr=max(socerr,-0.01)
                socerr=min(socerr,0.01)
              config['battery']['ahloss']=config['battery']['ahloss']-socerr/2
              batconfigdata=SafeConfigParser()
              batconfigdata.read('battery.cfg')
              batconfigdata.set('battery','ahloss',str(config['battery']['ahloss']))
              with open('battery.cfg', 'w') as batconfig:
                batconfigdata.write(batconfig)
              batconfig.closed

              batdata.soc = 0.0
              batdata.socadj = 0.0
              summary['current']['dod'][3] = 0
            else:
              batdata.soc = batdata.soc + batdata.batah
              batdata.socadj = batdata.socadj +batdata.batahadj
            batdata.ah = batdata.ah + batdata.batah
            batdata.inahtot = batdata.inahtot + batdata.inah
            batdata.pwrbattot = batdata.pwrbattot + batdata.pwrbat
            batdata.pwrintot = batdata.pwrintot + batdata.pwrin
          prevbatvoltage = batdata.batvoltsav[numcells]
  # check alarms
          alarms.scanalarms(batdata)
  # update summaries
          logsummary.update(summary, batdata)
          if logsummary.currenttime[4] != logsummary.prevtime[4]:  # new minute
            loadconfig()
            logsummary.updatesection(summary, 'hour', 'current')
            logsummary.updatesection(summary, 'alltime','current')
            logsummary.updatesection(summary, 'currentday','current')
            logsummary.updatesection(summary, 'monthtodate', 'current')
            logsummary.updatesection(summary, 'yeartodate', 'current')
            logsummary.writesummary()
            batdata.ah = 0.0
            batdata.ahadj = 0.0
            batdata.inahtot = 0.0
            batdata.pwrbattot = 0.0
            batdata.pwrintot = 0.0
            for i in range(batdata.numiins):
              batdata.kWhin[i] = 0.0
              batdata.kWhout[i] = 0.0
            for i in range(numcells):
              batdata.baltime[i]=0


          if logsummary.currenttime[3] != logsummary.prevtime[3]:  # new hour
            logsummary.starthour(summary)

          if logsummary.currenttime[3] < logsummary.prevtime[3]: # newday
            logsummary.startday(summary)

          if logsummary.currenttime[1] != logsummary.prevtime[1]: # new month
            logsummary.startmonth(summary)

          if logsummary.currenttime[0] != logsummary.prevtime[0]: # new year
            logsummary.startyear(summary)

        except KeyboardInterrupt:
          sys.stdout.write('\n')
          logsummary.close()
          sys.exit(9)
          break
  except Exception as err:
    log.critical(err)
    raise
예제 #7
0
    if currenttime[8:10] != prevtime[8:10]:  # new hour
        logsummary.starthour(summary)

    if currenttime[6:8] != prevtime[6:8]:  # newday
        logsummary.startday(summary)

    if currenttime[4:6] != prevtime[4:6]:  # new month
        logsummary.startmonth(summary)

    if currenttime[0:4] != prevtime[0:4]:  # new year
        logsummary.startyear(summary)

import summary
logsummary = summary.Summary()
batdata = Readings()  # initialise batdata
alarms = Alarms(batdata, summary)  # initialise alarms


def deamon(soc=-1):
    """Battery Management deamon to run in background"""

    numtries = 0
    while True:
        try:
            initmain(soc)
            while True:
                mainloop()
                numtries = 0
        except KeyboardInterrupt:
            numtries = maxtries
            sys.stdout.write('\n')
예제 #8
0
class SensiTags:

    alarms = None
    bot = None

    def __init__(self, bot):
        self.alarms = Alarms(bot)


    def lastReg(self):
        self.alarms.updateAlarms()
        msgLastReg = ', aqui estão os últimos registros das suas SensiTags.\n\n'
        conn = sqlite3.connect(dataBaseDjangoDir)
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM tags_tag""")
        conn.commit()
        query = (cursor.fetchall())
        for tag in query:
            connSensi = sqlite3.connect(dataBaseSensiDir)
            cursorSensi = connSensi.cursor()
            #querySet = "SELECT * FROM reg WHERE MAC = '" + tag[1]+ "' order by id desc LIMIT 1"
            querySet = "SELECT * FROM reg WHERE MAC = '"+tag[1]+"' order by id desc LIMIT 1"
            cursorSensi.execute(querySet)
            connSensi.commit()
            querySensi = (cursorSensi.fetchall())
            for reg in querySensi:
                if len(reg) !=  0:
                    msgLastReg = msgLastReg + '*->* MAC: *' + reg[1] + '*\n'
                    msgLastReg = msgLastReg + '     Bateria: *' + str(reg[2]/1000) + 'V*\n'
                    msgLastReg = msgLastReg + '     Temperatura: *' + str(reg[3]) + 'º*\n'
                    msgLastReg = msgLastReg + '     Umidade: *' + str(reg[4]) + '%*\n'
                    msgLastReg = msgLastReg + "     Date : *" + str(reg[7]) + "/" + str(reg[6]) + "/" + str(reg[5]) + "*\n"
                    msgLastReg = msgLastReg + "     Hora : *" + str(reg[8]) + "h" + str(reg[9]) + "m" + str(reg[10]) + "s" + "*\n\n"
        return msgLastReg


    def getInfo(self):
        conn = sqlite3.connect(dataBaseDjangoDir)
        cursor = conn.cursor()
        cursor.execute("""select * from tags_tag""")
        conn.commit()
        query = (cursor.fetchall())
        msgTags = ", aqui estão as informações sobre as suas SensiTags.\n\n "
        for tag in query:
            msgTags = msgTags + '*->* MAC: *' + tag[1] + '*\n'
            msgTags = msgTags + '     Localização: *' + tag[2] + '*\n\n'
        return msgTags

    def getData(self):
        os.system('clear')
        macs = []
        conn = sqlite3.connect(dataBaseDjangoDir)
        cursor = conn.cursor()
        cursor.execute("""select * from tags_tag""")
        conn.commit()
        query = (cursor.fetchall())
        for tag in query:
            macs.append(tag[1])
        datas = RuuviTagSensor.get_data_for_sensors(macs, timeout_in_sec)
        # Dictionary will have lates data for each sensor
        for mac in macs:
            try:
                tag = datas[mac]
                date = datetime.datetime.now()
                TUPLA = (mac,
                         tag['battery'],
                         tag['temperature'],
                         tag['humidity'],
                         int(date.year),
                         int(date.month),
                         int(date.day),
                         int(date.hour),
                         int(date.minute),
                         int(date.second),
                         )

                vetor = [TUPLA, ]
                print("VETOR : ", vetor)

                try:
                    conn = sqlite3.connect(dataBaseSensiDir)
                    cursor = conn.cursor()
                    cursor.executemany("""
                        INSERT INTO reg (MAC, BATERIA, TEMPERATURA,UMIDADE,ANO,MES,DIA,HORA,MINUTO,SEGUNDO)
                        VALUES (?,?,?,?,?,?,?,?,?,?)
                        """, vetor)
                    conn.commit()
                    conn.close()
                except KeyError:
                    print ('erro do banco')

            except KeyError:
                print ('tag n encontrada: ' + mac)
예제 #9
0
 def __init__(self, bot):
     self.alarms = Alarms(bot)
예제 #10
0
    def _setup_ui(self):
        column_layout = QHBoxLayout()
        self.setLayout(column_layout)
        column_layout.setMargin(0)
        column_layout.setSpacing(1)

        col1_layout = QVBoxLayout()
        col1_layout.setMargin(0)
        column_layout.addLayout(col1_layout)

        self._write_w = WriteW(self, self._usbif)
        col1_layout.addWidget(self._write_w)
        col1_layout.setAlignment(self._write_w, Qt.AlignTop | Qt.AlignLeft)

        col2_layout = QVBoxLayout()
        col2_layout.setMargin(0)
        col2_layout.setSpacing(2)
        col2_layout.addSpacing(10)
        column_layout.addLayout(col2_layout)

        regs_layout = QVBoxLayout()
        regs_layout.setSpacing(2)
        regs_layout.setMargin(0)
        col2_layout.addLayout(regs_layout)
        col2_layout.setAlignment(regs_layout, Qt.AlignTop)

        # Add all of the registers for display
        self._reg_a = Register(self, self._usbif, 'A', False, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_a)
        regs_layout.setAlignment(self._reg_a, Qt.AlignRight)

        self._reg_l = Register(self, self._usbif, 'L', False, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_l)
        regs_layout.setAlignment(self._reg_l, Qt.AlignRight)

        # self._reg_y = Register(regs, self._usbif, 'Y', False, QColor(0, 255, 0))
        # regs_layout.addWidget(self._reg_y)
        # regs_layout.setAlignment(self._reg_y, Qt.AlignRight)

        # self._reg_u = Register(regs, self._usbif, 'U', False, QColor(0, 255, 0))
        # regs_layout.addWidget(self._reg_u)
        # regs_layout.setAlignment(self._reg_u, Qt.AlignRight)

        self._reg_z = Register(self, self._usbif, 'Z', False, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_z)
        regs_layout.setAlignment(self._reg_z, Qt.AlignRight)

        # self._reg_q = Register(regs, self._usbif, 'Q', False, QColor(0, 255, 0))
        # regs_layout.addWidget(self._reg_q)
        # regs_layout.setAlignment(self._reg_q, Qt.AlignRight)

        self._reg_g = Register(self, self._usbif, 'G', True, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_g)
        regs_layout.setAlignment(self._reg_g, Qt.AlignRight)

        # self._reg_b = Register(regs, self._usbif, 'B', False, QColor(0, 255, 0))
        # regs_layout.addWidget(self._reg_b)
        # regs_layout.setAlignment(self._reg_b, Qt.AlignRight)

        self._reg_w = Register(self, self._usbif, 'W', True, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_w)
        regs_layout.setAlignment(self._reg_w, Qt.AlignRight)

        self._w_cmp = WComparator(self, self._usbif)
        regs_layout.addWidget(self._w_cmp)
        regs_layout.setAlignment(self._w_cmp, Qt.AlignRight)

        col2_layout.addSpacing(10)

        self._reg_s = AddressRegister(self, self._usbif, QColor(0, 255, 0))
        col2_layout.addWidget(self._reg_s)
        col2_layout.setAlignment(self._reg_s, Qt.AlignRight)

        self._s1_comp = SComparator(self, self._usbif, 1)
        col2_layout.addWidget(self._s1_comp)
        col2_layout.setAlignment(self._s1_comp, Qt.AlignRight)

        self._s2_comp = SComparator(self, self._usbif, 2)
        col2_layout.addWidget(self._s2_comp)
        col2_layout.setAlignment(self._s2_comp, Qt.AlignRight)

        col2_layout.addSpacing(10)

        self._reg_i = InstructionRegister(self, self._usbif, QColor(0, 255, 0))
        col2_layout.addWidget(self._reg_i)
        col2_layout.setAlignment(self._reg_i, Qt.AlignRight)

        self._i_comp = IComparator(self, self._usbif)
        col2_layout.addWidget(self._i_comp)
        col2_layout.setAlignment(self._i_comp, Qt.AlignRight)

        col2_layout.addSpacing(10)
        col2_layout.addStretch(1000)


        col3 = QWidget(self)
        col3_layout = QVBoxLayout(col3)
        col3_layout.setMargin(0)
        col3_layout.setSpacing(2)
        #col3_layout.addSpacing(10)
        column_layout.addWidget(col3)

        # Add the alarms panel
        self._alarms_panel = Alarms(col3, self._usbif)
        col3_layout.addWidget(self._alarms_panel)
        col3_layout.setAlignment(self._alarms_panel, Qt.AlignTop | Qt.AlignRight)

        # Add the control panel
        self._ctrl_panel = Control(col3, self._usbif)
        col3_layout.addWidget(self._ctrl_panel)
        col3_layout.setAlignment(self._ctrl_panel, Qt.AlignTop | Qt.AlignRight)

        # Add the computer stop panel
        self._comp_stop = CompStop(col3, self._usbif)
        col3_layout.addWidget(self._comp_stop)
        col3_layout.setAlignment(self._comp_stop, Qt.AlignTop | Qt.AlignRight)

        # Add the read/load panel
        self._read_load = ReadLoad(col3, self._usbif)
        col3_layout.addWidget(self._read_load)
        col3_layout.setAlignment(self._read_load, Qt.AlignTop | Qt.AlignRight)

        # Add the fixed memory panel
        self._fixed = FixedMemory(col3, self._usbif)
        col3_layout.addWidget(self._fixed)
        col3_layout.setAlignment(self._fixed, Qt.AlignTop | Qt.AlignRight)

        # Add the erasable memory panel
        self._erasable = ErasableMemory(col3, self._usbif)
        col3_layout.addWidget(self._erasable)
        col3_layout.setAlignment(self._erasable, Qt.AlignTop | Qt.AlignRight)

        col3_layout.addStretch()

        self.show()
예제 #11
0
class App(tk.Tk):
    def __init__(self, width, height):
        self.width = width
        self.height = height
        tk.Tk.__init__(self)
        self.configure_window()
        self.add_widgets()

    def configure_window(self):
        self.title("Alarm Clock")
        self.geometry(f"{self.width}x{self.height}+100+100")
        self.minsize(600, 185)
        image_path = relpath("alarm-clock/assets/pictures/icon_2.ico")
        image = ImageTk.PhotoImage(file=image_path)
        self.iconphoto(False, image)

    def add_widgets(self):
        # Tabbed view
        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill=tk.BOTH, expand=1)
        self.notebook.bind("<<NotebookTabChanged>>", self.manage_threads)

        # First Tab: Alarms
        self.alarms = Alarms(self.notebook)
        self.protocol("WM_DELETE_WINDOW", self.on_close)
        self.alarms.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.alarms, text="Alarms")

        # Second Tab: Clock (Hopefully will add analog and digital)
        self.clock = Clock(self.notebook)
        self.clock.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.clock, text="Clock")

        # Third Tab: Stopwatch
        self.stopwatch = Stopwatch(self.notebook)
        self.stopwatch.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.stopwatch, text="Stopwatch")

        # Fourth Tab: Timer
        self.timer = Timer(self.notebook)
        self.timer.pack(fill=tk.BOTH, expand=1)
        self.notebook.add(self.timer, text="Timer")

    def manage_threads(self, event):
        active_tab = self.notebook.tab(self.notebook.select(), "text")
        if active_tab == "Alarms":
            if self.clock.thread.is_alive():
                self.clock.kill = True
                self.clock.thread.join()
            elif self.stopwatch.thread.is_alive():
                self.stopwatch.kill = True
                self.stopwatch.thread.join()
            elif self.timer.thread.is_alive():
                self.timer.kill = True
                self.timer.thread.join()
        elif active_tab == "Clock":
            if self.stopwatch.thread.is_alive():
                self.stopwatch.kill = True
                self.stopwatch.thread.join()
            elif self.timer.thread.is_alive():
                self.timer.kill = True
                self.timer.thread.join()
            self.clock.kill = False
            self.clock.thread = Thread(target=self.clock.update, daemon=True)
            self.clock.thread.start()
        elif active_tab == "Stopwatch":
            if self.clock.thread.is_alive():
                self.clock.kill = True
                self.clock.thread.join()
            elif self.timer.thread.is_alive():
                self.timer.kill = True
                self.timer.thread.join()
            self.stopwatch.kill = False
            self.stopwatch.thread = Thread(target=self.stopwatch.update,
                                           daemon=True)
            self.stopwatch.thread.start()
        elif active_tab == "Timer":
            if self.clock.thread.is_alive():
                self.clock.kill = True
                self.clock.thread.join()
            elif self.stopwatch.thread.is_alive():
                self.stopwatch.kill = True
                self.stopwatch.thread.join()
            self.timer.kill = False
            self.timer.thread = Thread(target=self.timer.update, daemon=True)
            self.timer.thread.start()

    def on_close(self):
        self.alarms.db.close()
        self.destroy()

    def start(self):
        self.mainloop()
예제 #12
0
class FaceDetection(object):
    """Esta clase detecta un rostro y sus landmarks"""
    def __init__(self):
        """Constructor, esto es lo que se ejecuta cuando se crea un objeto de la clase FaceDetection."""

        self.frame = None
        self.counter = 0
        self.EYE_AR_THRESH = 0.15
        self.EYE_AR_CONSEC_FRAMES = 2
        self.YAWN_THRESH = 10
        self.face_detected = False
        self.yawn_counter = 0
        self.CAR_REGISTRATION = 'SAF 6245'

        self.blink_verification = False
        self.blink_counter = 0
        self.t_end_blink = 0  #Variable para controlar alarma cuando los ojos se cierran
        self.BLINK_TIME_CLOSED = 1  # Tiempo en segundos para que se considere un parpadeo largo
        self.BLINK_TIME_GAP = 60  # el tiempo por el cuazl quedan guardado los parpadeos largos en el array
        self.BLINK_TIME_ALERT = 2  # cantidad de veces que se produscan pestaneos largos antes de que se dispare una alerta
        self.blink_time_alert_counter_a = [
        ]  # se guardan los moentos en que se detectaron los parpadeos largos
        self.blink_counter_verification = False  #veriable que permite verificar el momento de trasiciondes de estado del ojo(de abierto a cerrado)
        self.blink_eye_closed = 0  # momento en el que se detecto que el ojo se cerro

        self.yawn_closed = 0
        self.yawn_counter_verification = False
        self.t_end = 0  #Variable para controlar el tiempo de un bostezo
        self.YAWN_TIME_GAP = 60  #
        self.YAWN_TIME_ALERT = 2  # Cantidad de bostetzos por minuto para que se active la alarma
        self.yawn_time_alert_counter_a = [
        ]  #se guardan los bostezos (se guarda en formato time)
        self.t_end_alarm = 0
        self.EVENT_STRING_DROWSINESS = 'Sintomas de suenio'
        self.EVENT_STRING_SLEEP = 'Dormido'
        self.EVENT_STRING_DISTRACTION = 'Distraccion'
        self.face_angle_vertical = 0.0
        self.face_angle_horizontal = 0.0
        self.face_angle_horizontal = 0.0
        self.alarm = Alarms()

        #_face_detector detecta rostros
        self._face_detector = dlib.get_frontal_face_detector()

        #_predictor es usado para obtener los landmarks de una cara
        self._predictor = dlib.shape_predictor(
            path + "/shape_predictor_68_face_landmarks.dat")

    def set_gps(self, gps):
        self.gps = gps

    def _analyze(self):
        """Detecta un rostro y todos sus landmarks"""

        frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
        faces = self._face_detector(frame)
        self.face_detected = True if faces else False

        if self.face_detected:
            self.raw_landmarks = self._predictor(frame, faces[0])
            self.landmarks = face_utils.shape_to_np(self.raw_landmarks)
            self.final_ear(self.landmarks)
            self.lips_distance = self.lip_distance(self.landmarks)
        else:
            self.alarm.lost_face()
            self.left_eye = None
            self.right_eye = None

    def refresh(self, frame):
        """Refresca el frame y lo analiza."""

        self.frame = frame
        self.frame_clean = frame
        self._analyze()

    def final_ear(self, shape):
        """ Setea los ojos y las orejas """

        (l_start, l_end) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
        (r_start, r_end) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]

        self.left_eye = shape[l_start:l_end]
        self.right_eye = shape[r_start:r_end]

        self.left_ear = self.eye_aspect_ratio(self.left_eye)
        self.right_ear = self.eye_aspect_ratio(self.right_eye)

        self.ear = (self.left_ear + self.right_ear) / 2.0

    def eye_aspect_ratio(self, eye):
        A = dist.euclidean(eye[1], eye[5])
        B = dist.euclidean(eye[2], eye[4])
        C = dist.euclidean(eye[0], eye[3])

        ear = (A + B) / (2.0 * C)
        return ear

    def lip_distance(self, shape):
        """Calcula la distancia entre el labio superior e inferior"""

        top_lip = shape[50:53]
        top_lip = np.concatenate((top_lip, shape[61:64]))

        low_lip = shape[56:59]
        low_lip = np.concatenate((low_lip, shape[65:68]))

        top_mean = np.mean(top_lip, axis=0)
        low_mean = np.mean(low_lip, axis=0)

        distance = abs(top_mean[1] - low_mean[1])
        return distance

    def draw_landmarks(self):
        """Dibuja en el frame los landmarks"""
        if self.face_detected:
            left_eye_hull = cv2.convexHull(self.left_eye)
            right_eye_hull = cv2.convexHull(self.right_eye)
            cv2.drawContours(self.frame, [left_eye_hull], -1, (0, 255, 0), 1)
            cv2.drawContours(self.frame, [right_eye_hull], -1, (0, 255, 0), 1)
            lip = self.landmarks[48:60]
            cv2.drawContours(self.frame, [lip], -1, (0, 255, 0), 1)

    def check_drowsiness(self):
        """Conteo de pestaneos, bostezos y detección de sueño"""

        self.blink_drowsiness_symptoms = 8

        if self.ear < self.EYE_AR_THRESH:
            if ((self.counter <= time.time() - self.EYE_AR_CONSEC_FRAMES)
                    and self.t_end_blink == 0):
                self.t_end_blink = time.time() + 5
                self.alarm.text_to_speech("alarm")  #El conductor se durmió
                CsvHandler.csv_input(
                    self.CAR_REGISTRATION, self.EVENT_STRING_SLEEP,
                    '' + str(self.gps.get_lat()) +
                    ', ' + str(self.gps.get_lon()) + '',
                    str(self.gps.get_speed()), self.frame)

        else:
            self.counter = time.time()

        if (time.time() > self.t_end_blink):
            self.t_end_blink = 0

        # conteo de pestaneos

        if self.ear < self.EYE_AR_THRESH:
            self.blink_verification = True
        else:
            if self.blink_verification == True:
                self.blink_verification = False
                self.blink_counter += 1
                print("Cantidad de pestaneos: ", self.blink_counter)

        # control de pestaneos largos en un tiempo a definir
        if self.ear < self.EYE_AR_THRESH:
            if self.blink_counter_verification == True:
                self.blink_counter_verification = False
                self.blink_eye_closed = time.time() + self.BLINK_TIME_CLOSED
            if time.time(
            ) >= self.blink_eye_closed and self.blink_eye_closed != 0:
                self.blink_time_alert_counter_a.append(time.time())
                self.blink_eye_closed = 0
                print("Se subio el contador de sintomas (pestaneos) en 1",
                      self.blink_time_alert_counter_a)
                if len(self.blink_time_alert_counter_a
                       ) == self.BLINK_TIME_ALERT:
                    self.blink_time_alert_counter_a = []
                    self.alarm.text_to_speech("drows_alert")
                    CsvHandler.csv_input(
                        self.CAR_REGISTRATION, self.EVENT_STRING_DROWSINESS,
                        '' + str(self.gps.get_lat()) +
                        ', ' + str(self.gps.get_lon()),
                        str(self.gps.get_speed()), self.frame)

        else:
            self.blink_counter_verification = True
            self.blink_eye_closed = 0

        # solamente mantiene los pestaneos que se relaizaron en el intervalo de un minuto hacia atras, el resto los elimina
        if len(self.blink_time_alert_counter_a) > 0:
            if self.blink_time_alert_counter_a[0] <= (time.time() -
                                                      self.BLINK_TIME_GAP):
                self.blink_time_alert_counter_a.pop(0)
                print("elimine un elemento (pestaneo) porque paso un min",
                      self.blink_time_alert_counter_a)

        # bostezos

        if self.lips_distance > self.YAWN_THRESH and self.t_end == 0:
            self.t_end = time.time() + 5
            if self.yawn_counter_verification == True:
                self.yawn_counter_verification = False
                self.yawn_time_alert_counter_a.append(time.time())
                print("se a incrementado en 1 bostezos",
                      self.yawn_time_alert_counter_a)
                if len(self.yawn_time_alert_counter_a) == self.YAWN_TIME_ALERT:
                    self.alarm.text_to_speech("drows_alert")
                    self.yawn_time_alert_counter_a = []
        else:
            self.yawn_counter_verification = True

        if len(self.yawn_time_alert_counter_a) > 0:
            if self.yawn_time_alert_counter_a[0] <= (time.time() -
                                                     self.YAWN_TIME_GAP):
                self.yawn_time_alert_counter_a.pop(0)
                print("se elimino un lemento (Bostezo) porque paso un min",
                      self.yawn_time_alert_counter_a)

        if (time.time() > self.t_end):
            self.t_end = 0

    def head_pose_estimation(self):
        """Obtener e imprimir en pantalla los angulos de euler de la cabeza"""

        landmark_coords = np.zeros((self.raw_landmarks.num_parts, 2),
                                   dtype="int")

        # 2D model points
        image_points = np.float32([
            (self.raw_landmarks.part(30).x,
             self.raw_landmarks.part(30).y),  # nose
            (self.raw_landmarks.part(8).x,
             self.raw_landmarks.part(8).y),  # Chin
            (self.raw_landmarks.part(36).x,
             self.raw_landmarks.part(36).y),  # Left eye left corner
            (self.raw_landmarks.part(45).x,
             self.raw_landmarks.part(45).y),  # Right eye right corner
            (self.raw_landmarks.part(48).x,
             self.raw_landmarks.part(48).y),  # Left Mouth corner
            (self.raw_landmarks.part(54).x,
             self.raw_landmarks.part(54).y),  # Right mouth corner
            (self.raw_landmarks.part(27).x, self.raw_landmarks.part(27).y)
        ])

        # 3D model points
        model_points = np.float32([
            (0.0, 0.0, 0.0),  # Nose tip
            (0.0, -330.0, -65.0),  # Chin
            (225.0, 170.0, -135.0),  # Left eye left corner
            (-225.0, 170.0, -135.0),  # Right eye right corner
            (150.0, -150.0, -125.0),  # Left Mouth corner
            (-150.0, -150.0, -125.0),  # Right mouth corner
            (0.0, 140.0, 0.0)
        ])

        frame = self.frame

        # image properties. channels is not needed so _ is to drop the value
        height, width, _ = frame.shape

        # Camera internals double
        focal_length = width
        center = np.float32([width / 2, height / 2])
        camera_matrix = np.float32([[focal_length, 0.0, center[0]],
                                    [0.0, focal_length, center[1]],
                                    [0.0, 0.0, 1.0]])
        dist_coeffs = np.zeros((4, 1),
                               dtype="float32")  #Assuming no lens distortion

        retval, rvec, tvec = cv2.solvePnP(model_points, image_points,
                                          camera_matrix, dist_coeffs)

        nose_end_point3D = np.float32([[50, 0, 0], [0, 50, 0], [0, 0, 50]])

        nose_end_point2D, jacobian = cv2.projectPoints(nose_end_point3D, rvec,
                                                       tvec, camera_matrix,
                                                       dist_coeffs)

        rotCamerMatrix, _ = cv2.Rodrigues(rvec)

        euler_angles = self.get_euler_angles(rotCamerMatrix)

        # Filter angle
        self.face_angle_vertical = (
            0.5 * euler_angles[0]) + (1.0 - 0.5) * self.face_angle_vertical
        self.face_angle_horizontal = (
            0.5 * euler_angles[1]) + (1.0 - 0.5) * self.face_angle_horizontal

        euler_angles[0] = self.face_angle_vertical
        euler_angles[1] = self.face_angle_horizontal

        pitch = "Vertical: {}".format(self.face_angle_vertical)
        yaw = "Horizontal: {}".format(self.face_angle_horizontal)

        #cv2.putText(self.frame, pitch, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
        #           0.5, (0, 0, 255), 2)
        #cv2.putText(self.frame, yaw, (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
        #           0.5, (0, 255, 0), 2)

    def get_euler_angles(self, camera_rot_matrix):
        """Obtener los angulos de Euler de la cabeza"""

        rt = cv2.transpose(camera_rot_matrix)
        shouldBeIdentity = np.matmul(rt, camera_rot_matrix)
        identity_mat = np.eye(3, 3, dtype="float32")

        isSingularMatrix = cv2.norm(identity_mat, shouldBeIdentity) < 1e-6

        euler_angles = np.float32([0.0, 0.0, 0.0])
        if not isSingularMatrix:
            return euler_angles

        sy = math.sqrt(camera_rot_matrix[0, 0] * camera_rot_matrix[0, 0] +
                       camera_rot_matrix[1, 0] * camera_rot_matrix[1, 0])

        singular = sy < 1e-6

        if not singular:
            x = math.atan2(camera_rot_matrix[2, 1], camera_rot_matrix[2, 2])
            y = math.atan2(-camera_rot_matrix[2, 0], sy)
            z = math.atan2(camera_rot_matrix[1, 0], camera_rot_matrix[0, 0])
        else:
            x = math.atan2(-camera_rot_matrix[1, 2], camera_rot_matrix[1, 1])
            y = math.atan2(-camera_rot_matrix[2, 0], sy)
            z = 0

        x = x * 180.0 / math.pi
        y = y * 180.0 / math.pi
        z = z * 180.0 / math.pi

        euler_angles[0] = -x
        euler_angles[1] = y
        euler_angles[2] = z

        return euler_angles

    def initial_setup(self):
        """Setup de los angulos iniciales de euler de la cabeza"""

        self.alarm.text_to_speech("introduction")
        time.sleep(10)
        self.head_pose_estimation()
        self.initial_face_angle_vertical = self.face_angle_vertical
        self.initial_face_angle_horizontal = self.face_angle_horizontal

        print('Angulo vertical: ', self.initial_face_angle_vertical,
              ' Angulo horizontal: ', self.initial_face_angle_horizontal)
        self.alarm.text_to_speech("configuration_finished")

    def check_distraction(self):
        """Se detecta una distraccion en caso de que se pase un umbral con respecto a los angulos de euler originales"""

        vertical_threshold = 10
        horizontal_threshold = 25
        vertical_lower_bound = self.initial_face_angle_vertical - vertical_threshold
        horizontal_lower_bound = self.initial_face_angle_horizontal - horizontal_threshold
        horizontal_upper_bound = self.initial_face_angle_horizontal + horizontal_threshold
        if (self.face_angle_vertical < vertical_lower_bound
                or self.face_angle_horizontal < horizontal_lower_bound
                or self.face_angle_horizontal > horizontal_upper_bound):

            if (self.alarm.lost_face()):
                CsvHandler.csv_input(
                    self.CAR_REGISTRATION, self.EVENT_STRING_DISTRACTION,
                    '' + str(self.gps.get_lat()) +
                    ', ' + str(self.gps.get_lon()) + '',
                    str(self.gps.get_speed()), self.frame)
                print("Distraccion detectada y registrada")
예제 #13
0
 def __init__(self):
     self.alarms = Alarms(self)
     self.make_table()
     self.fill_table()
     self.status = Label()
     self.panel = self.make_panel()
예제 #14
0
class AlarmWidget(object):
    weekday_name = { 0: 'Mo', 1: 'Di', 2: 'Mi', 3: 'Do', 4: 'Fr', 5: 'Sa', 6: 'So' }

    def __init__(self):
        self.alarms = Alarms(self)
        self.make_table()
        self.fill_table()
        self.status = Label()
        self.panel = self.make_panel()

    def make_panel(self):
        message = Label(
            'The configuration has been changed.\n'
            'You must apply the changes in order for them to take effect.')
        DOM.setStyleAttribute(message.getElement(), "whiteSpace", 'pre')

        msgbox = Grid(1, 2, StyleName='changes')
        msgbox.setWidget(0, 0, Image('icons/exclam.png'))
        msgbox.setWidget(0, 1, message)
        msgbox.getCellFormatter().setStyleName(0, 0, 'changes-image')
        msgbox.getCellFormatter().setStyleName(0, 1, 'changes-text')

        button = Button('apply changes')
        button.addClickListener(self.apply_clicked)

        self.changes = VerticalPanel()
        self.changes.setHorizontalAlignment('right')
        self.changes.setVisible(False)
        self.changes.add(msgbox)
        self.changes.add(button)

        panel = VerticalPanel()
        panel.setSpacing(10)
        panel.add(self.table)
        panel.add(self.status)
        panel.add(self.changes)

        return panel

    def make_table(self):
        self.table = FlexTable(StyleName='alarms')
        self.table.setBorderWidth(1)
        self.make_header()
        self.make_footer()

    def make_header(self):
        headers = [ 'Time', 'Days', 'Duration' ]
        for col, text in enumerate(headers):
            self.table.setText(0, col, text)
            self.table.getCellFormatter().setStyleName(0, col, 'tablecell header')

    def make_footer(self):
        self.time = {}

        self.time['hour'] = ListBox()
        self.time['hour'].setVisibleItemCount(1)
        for hour in range(24):
            self.time['hour'].addItem('%02d' % hour)
        self.time['hour'].setSelectedIndex(12)

        self.time['minute'] = ListBox()
        self.time['minute'].setVisibleItemCount(1)
        for minute in range(0, 60, 5):
            self.time['minute'].addItem('%02d' % minute)
        self.time['minute'].setSelectedIndex(0)

        time_panel = HorizontalPanel()
        time_panel.setVerticalAlignment('center')
        time_panel.add(self.time['hour'])
        time_panel.add(Label(':'))
        time_panel.add(self.time['minute'])
        self.table.setWidget(1, 0, time_panel)

        weekdays_panel = HorizontalPanel()
        weekdays_panel.setSpacing(5)
        self.weekdays = {}
        for i in range(7):
            self.weekdays[i] = CheckBox(AlarmWidget.weekday_name[i])
            self.weekdays[i].setChecked(i < 6)
            weekdays_panel.add(self.weekdays[i])
        self.table.setWidget(1, 1, weekdays_panel)

        self.duration = ListBox()
        self.duration.setVisibleItemCount(1)
        choices = [ 1, 2, 3, 4, 5, 7, 10, 15, 20, 25, 30, 40, 50, 60 ]
        for seconds in choices:
            self.duration.addItem(
                    '%ds' % seconds if seconds < 60 else '%dm' % (seconds / 60),
                    seconds)
        self.duration.setSelectedIndex(2)
        self.table.setWidget(1, 2, self.duration)

        image = Image('icons/plus.png')
        image.setTitle('add');
        image.addClickListener(self.plus_clicked)
        self.table.setWidget(1, 3, image)

        for col in range(4):
            self.table.getCellFormatter().setStyleName(1, col, 'tablecell noborder')

    def fill_table(self):
        for idx, alarm in enumerate(self.alarms.get()):
            self.add(alarm['time'], alarm['weekdays'], alarm['duration'])

    def add(self, time, weekdays=range(5), duration=3):
        row = self.table.getRowCount()-1
        self.table.insertRow(row)
        self.table.setText(row, 0, time)
        weekdays_str = []
        for weekday in weekdays:
            weekdays_str.append(AlarmWidget.weekday_name[weekday])

        self.table.setText(row, 1, ', '.join(weekdays_str))
        self.table.setText(row, 2, str(duration) + 's')

        image = Image('icons/x.png')
        image.setTitle('delete');
        image.addClickListener(lambda x: self.x_clicked(row-1))
        self.table.setWidget(row, 3, image)

        for col in range(3):
            self.table.getCellFormatter().setStyleName(row, col, 'tablecell')
        self.table.getCellFormatter().setStyleName(row, 3, 'tablecell noborder')

    def remove(self, idx):
        if idx >= 0 and idx < self.table.getRowCount()-2:
            #self.status.setText('removing idx: %d' % idx)
            self.table.removeRow(idx+1)
        else:
            #self.status.setText('tried to remove idx: %d' % idx)
            pass

    def plus_clicked(self):
        self.changes.setVisible(True)
        getSelectedValue = lambda widget: widget.getValue(widget.getSelectedIndex())
        hour = getSelectedValue(self.time['hour'])
        minute = getSelectedValue(self.time['minute'])
        time = '%02d:%02d:%02d' % ( hour, minute, 0 )
        weekdays = [ i for i in range(7) if self.weekdays[i].isChecked() ]
        duration = getSelectedValue(self.duration)

        self.add(time, weekdays, duration)
        self.alarms.add({'time': time, 'weekdays': weekdays, 'duration': duration})

    def x_clicked(self, idx):
        self.changes.setVisible(True)
        self.remove(idx)
        #self.alarms.remove(idx)

    def apply_clicked(self):
        self.alarms.save()
        self.changes.setVisible(False)