def get_arret_stat(self, ts): self.arret_time_matin = 0 self.imprevu_arret_time_matin = 0 self.arret_time_soir = 0 self.imprevu_arret_time_soir = 0 vendredi = is_vendredi(ts) time_change_of_team = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN ts_change_of_team = timestamp_at_time(ts, hours=time_change_of_team) arrets = self.arrets for arret in arrets: start_arret = arret[0] end_arret = arret[1] if vendredi and end_arret > timestamp_at_time( ts, hours=FIN_PROD_SOIR_VENDREDI): arret_delay = timestamp_at_time( ts, hours=FIN_PROD_SOIR_VENDREDI) - start_arret else: arret_delay = end_arret - start_arret if start_arret <= ts_change_of_team > end_arret: self.arret_time_matin += arret_delay elif start_arret <= ts_change_of_team < end_arret: self.arret_time_matin += ts_change_of_team - start_arret self.arret_time_soir += end_arret - ts_change_of_team else: self.arret_time_soir += arret_delay if arret[2]: first_raison = arret[2][0] if first_raison.type == "Imprévu": if start_arret <= ts_change_of_team > end_arret: self.imprevu_arret_time_matin += arret_delay elif start_arret <= ts_change_of_team < end_arret: self.imprevu_arret_time_matin += ts_change_of_team - start_arret self.imprevu_arret_time_soir += end_arret - ts_change_of_team else: self.imprevu_arret_time_soir += arret_delay
def update_data(self, prods, events, day_ago): self.start_day = timestamp_at_time(timestamp_at_day_ago(day_ago), hours=DEBUT_PROD_MATIN) self.end_day = timestamp_at_time(timestamp_at_day_ago(day_ago), hours=FIN_PROD_SOIR) self.prods = prods self.events = events self.update_ui()
def add_defaut_stop_prod(self): day_ago = settings_store_gestion.day_ago start_defaut_stop_prod = timestamp_at_time( timestamp_at_day_ago(day_ago), hours=FIN_PROD_SOIR_VENDREDI) end_defaut_stop_prod = timestamp_at_time(timestamp_at_day_ago(day_ago), hours=FIN_PROD_SOIR) Database.create_event_prod(start=start_defaut_stop_prod, end=end_defaut_stop_prod, p_type="stop") self.update()
def update_plans_prods(self, tasks=None, day_ago=None): def get_end_from_index_task(index, p_day_ago): for p_task in tasks: if p_task.index == index and p_task.day_ago == p_day_ago: return p_task.plan_prod.end def get_task_from_index(index, p_day_ago): for p_task in tasks: if p_task.index == index and p_task.day_ago == p_day_ago: return p_task day_ago_for_next_update = [] current_day_ago = self.day_ago if day_ago is None else day_ago if tasks is None: tasks = self.get_tasks_at_day_ago(day_ago=current_day_ago) for task in tasks: if task.index == 0: if current_day_ago != task.day_ago: current_day_ago = task.day_ago from gestion.stores.plan_prod_store import plan_prod_store start_day = timestamp_at_time( timestamp_at_day_ago(day_ago=current_day_ago), hours=DEBUT_PROD_MATIN) last_plan_prod = plan_prod_store.get_last_plan_prod( start_plan_prod=start_day) task.plan_prod.update_from_start(start=start_day, last_plan_prod=last_plan_prod) else: last_plan_prod = get_task_from_index( task.index - 1, p_day_ago=current_day_ago).plan_prod start = get_end_from_index_task(index=task.index - 1, p_day_ago=current_day_ago) fin_prod = FIN_PROD_SOIR_VENDREDI if is_vendredi( last_plan_prod.start) else FIN_PROD_SOIR if start > timestamp_at_time( timestamp_at_day_ago(day_ago=current_day_ago), hours=fin_prod): start = timestamp_at_time( timestamp_at_day_ago(day_ago=current_day_ago - 1), hours=DEBUT_PROD_MATIN - 1) task.plan_prod.update_from_start( start=start, last_plan_prod=last_plan_prod) if current_day_ago - 1 not in day_ago_for_next_update: day_ago_for_next_update.append(current_day_ago - 1) else: task.plan_prod.update_from_start( start=start, last_plan_prod=last_plan_prod) self.update_plan_prod_on_database(plan_prod=task.plan_prod) from gestion.stores.plan_prod_store import plan_prod_store plan_prod_store.sort_plans_prods() if day_ago_for_next_update: for day_ago in day_ago_for_next_update: self.update_plans_prods(day_ago=day_ago) self.SETTINGS_CHANGED_SIGNAL.emit()
def get_metrage(ts, speeds, moment): data_ts = get_start_and_end(ts, moment) start_ts = timestamp_at_time(ts, hours=data_ts[0]) end_ts = timestamp_at_time(ts, hours=data_ts[1]) def value_is_in_period(value): return start_ts <= value[0] <= end_ts speeds_moment = [ v[1] for v in list(filter(value_is_in_period, speeds)) ] return speeds_moment
def list_new_arret_data(self): """ S'occupe de créer la liste des arrêts machines du store par rapport aux nouvelles données :return: Un tableau de tuple de timestamp (début de l'arrêt, fin de l'arrêt) """ # Récupère la liste des vitesses speeds = self.data # Récupère le timestamp du jours du store ts = timestamp_at_day_ago(self.day_ago) # Test si on est un vendredi vendredi = is_vendredi(ts) # Les équipes commence toujours à 6H start = DEBUT_PROD_MATIN # La fin de journée est 22h sauf le vendredi 20h end = FIN_PROD_SOIR_VENDREDI if vendredi else FIN_PROD_SOIR # Définit les bornes de recherche d'arrêt dans les données start_ts = timestamp_at_time(ts, hours=start) end_ts = timestamp_at_time(ts, hours=end) # Initialisation des variables speed_is_0 = False arrets = [] start = 0 end = 0 # On boucle sur le tableau de vitesse de store for value in speeds: # On test si la vitesse est dans la borne de recherche if value[0] < end_ts: # On test si la vitesse est inférieure à 60 # On assimile une vitesse inférieure à 60 à machine à l'arrêt if 0 <= value[1] <= VITESSE_LIMITE_ASSIMILATION_ARRET: # Si on est pas déja dans un arrêt on définit le début de l'arrêt if not speed_is_0: start = value[0] end = value[0] speed_is_0 = True # Si on vient de sortir d'un arrêt on ajoute l'arrêt à la liste d'arrêts elif speed_is_0: if start != end: arrets.append((start, end)) start = 0 end = 0 speed_is_0 = False else: continue # Si on sort de la boucle avec un arrêt en cours on ajoute le dernier arrêt à la liste d'arrêts if speed_is_0 and start != end: arrets.append((start, end)) return arrets
def get_start_for_new_plan_prod(self): tasks = self.get_tasks_at_day_ago(day_ago=self.day_ago) start = timestamp_at_time(timestamp_at_day_ago(self.day_ago), hours=DEBUT_PROD_MATIN) for task in tasks: if task.start == start: start = task.end return start
def get_arret(self): """ S'occupe de créer une liste de models Arret pour le moment de la journée courante :return: """ # Récupere le store courant store = data_store_manager.get_current_store() # Stock la liste des arrets trier par ordre croissant (par rapport au start) arrets = store.arrets # Récupere le dictionnaire des arrets dic_arret = store.dic_arret # Récupere le timestamp du jours actuel ts = timestamp_at_day_ago(self.day_ago) # Check si on est un vendredi # Dans ce cas les équipes travail 7h (6h-13h,13h-21h) vendredi = timestamp_to_day(ts) == "vendredi" start = DEBUT_PROD_MATIN mid = FIN_PROD_MATIN_VENDREDI if vendredi else DEBUT_PROD_SOIR end = FIN_PROD_SOIR_VENDREDI if vendredi else FIN_PROD_SOIR # Definit les bornes de sélection des arret en fonction du moment de la journée (matin ou soir) if self.moment == "matin": end = mid if self.moment == "soir": start = mid start_ts = timestamp_at_time(ts, hours=start) end_ts = timestamp_at_time(ts, hours=end) # Initialise la liste d'arret list_arret = [] # Parcours la liste des arret for arret in arrets: start_arret = arret[0] end_arret = arret[1] # Si le debut de l'arret est compris dans les bornes de selection if end_ts >= start_arret >= start_ts: # Et si la fin de l'arret est bien definit if end_arret > 0: # On ajoute a la liste des arrets l'models Arret stocké dans le dictionnaire list_arret.append(dic_arret[start_arret]) # Sinon on continue la boucle else: continue self.list_arret = list_arret
def get_total_time_prod(self, moment): """ Calcul le temps de production entre deux ts :param moment: Permet d'identifier la plage d'étude (matin, soir, total) :return: Le temps de production en s """ data_time = self.get_start_end() start = data_time[0] end = data_time[1] total_time_prod = 0 # On parcour tout les jours entre start et end current_day = start while current_day < end: # Vérifie si on est pas dans un jours du weekend if not self.is_weekend(ts_day=current_day): # On calcul le temps de production d'une journée normal current_time_prod = (FIN_PROD_SOIR - DEBUT_PROD_MATIN) * 3600 # On modifie le temps de production si on est vendredi vendredi = self.is_vendredi(ts_day=current_day) if vendredi: current_time_prod = (FIN_PROD_SOIR_VENDREDI - DEBUT_PROD_MATIN) * 3600 # Si la période est une demi-journée on divise par 2 if moment == "matin" or moment == "soir": current_time_prod /= 2 # On modifie le temps de production si on est en cour de journée if self.day_not_finish(ts_day=current_day, vendredi=vendredi, moment=moment): if moment == "soir": debut_prod = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN else: debut_prod = DEBUT_PROD_MATIN if timestamp_now() - timestamp_at_time( end, hours=debut_prod) < 0: break current_time_prod = timestamp_now() - timestamp_at_time( end, hours=debut_prod) total_time_prod += current_time_prod # Passe au jour suivant current_day = timestamp_after_day_ago(start=current_day, day_ago=1) return total_time_prod
def get_ratio_prod(moment): from production.stores.data_store_manager import data_store_manager current_store = data_store_manager.get_current_store() # Récupere le ts actuel ts_actuel = timestamp_now() # Calcul de la production maximum vendredi = timestamp_to_day(timestamp_at_day_ago( current_store.day_ago)) == "vendredi" if moment == "soir": debut_prod = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN else: debut_prod = DEBUT_PROD_MATIN if moment == "matin": fin_prod = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN else: fin_prod = FIN_PROD_SOIR_VENDREDI if vendredi else FIN_PROD_SOIR if ts_actuel < timestamp_at_time(current_store.start, hours=fin_prod): total_s = (ts_actuel - timestamp_at_time(current_store.start, hours=debut_prod)) else: total_s = 3600 * (fin_prod - debut_prod) max_prod = VITESSE_MOYENNE_MAXI * total_s / 60 # Calcul le métrage total de la période metrage_total = 0 if moment == "total": metrage_total = current_store.metrage_matin + current_store.metrage_soir if moment == "matin": metrage_total = current_store.metrage_matin if moment == "soir": metrage_total = current_store.metrage_soir # Calcul ratio if max_prod > 0 and metrage_total >= 0: ratio = metrage_total / max_prod * 100 if ratio > 100: ratio = 100 else: ratio = 0 return round(ratio, 1)
def day_not_finish(ts_day, vendredi, moment): """ Regarde si le jour est en cour :param ts_day: le timestamp du jour :param vendredi: True si on est vendredi sinon False :param moment: Période étudiée :return: True si le jour est en cour sinon False """ if moment == "matin": fin_prod = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN else: fin_prod = FIN_PROD_SOIR_VENDREDI if vendredi else FIN_PROD_SOIR return timestamp_now() < timestamp_at_time(ts_day, hours=fin_prod)
def get_metrage(data, vendredi): """ Calcul les metrages de l'equipe du matin et du soir Prend en compte si on est vendredi :param data: Les donnees triees par seconde :param vendredi: True si on traite des donnees d'un vendredi :return: Les valeurs arrondies du metrage matin et soir """ metrage_matin = 0 metrage_soir = 0 fin_prod_matin = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN for value in data: ts = value[0] metrage = value[1] / 60 if value[1] > 0 else 0 if ts < timestamp_at_time(ts, hours=fin_prod_matin): metrage_matin += metrage else: metrage_soir += metrage return round(metrage_matin), round(metrage_soir)
def is_valid_event(self): if self.start is None or self.end is None: self.status_label.setText( "Début ou fin de l'événement non renseigné") self.status_label.setStyleSheet(red_12_label_stylesheet) return False if get_hour_in_timestamp(self.start) < 6: self.status_label.setText("Début de l'événement avant 06:00") self.status_label.setStyleSheet(red_12_label_stylesheet) return False if self.end > timestamp_at_time(self.start, hours=22): self.status_label.setText("Fin de l'événement après 22:00") self.status_label.setStyleSheet(red_12_label_stylesheet) return False if self.end < self.start: self.status_label.setText("Fin de l'événement supérieur au début") self.status_label.setStyleSheet(red_12_label_stylesheet) return False self.status_label.setText("Evénement valide") self.status_label.setStyleSheet(green_12_label_stylesheet) return True
def create_bloc_arret(moment): vbox = QVBoxLayout() current_store = data_store_manager.get_current_store() arrets = current_store.arrets vendredi = timestamp_to_day(timestamp_at_day_ago(current_store.day_ago)) == "vendredi" if moment == "matin": start_hour = DEBUT_PROD_MATIN end_hour = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN else: start_hour = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN end_hour = FIN_PROD_SOIR_VENDREDI if vendredi else FIN_PROD_SOIR start_ts = timestamp_at_time(timestamp_at_day_ago(current_store.day_ago), hours=start_hour) end_ts = timestamp_at_time(timestamp_at_day_ago(current_store.day_ago), hours=end_hour) # Trie les arrets par ordre chronologique arrets = sorted(arrets, key=lambda arret: arret[0]) limit_imprevu = 0 def count_valid_arret(arrets, limit_imprevu): count = 0 for arret in arrets: start_arret = arret[0] end_arret = arret[1] type = arret[2][0].type if arret[2] else "non renseigné" if (start_ts <= start_arret <= end_ts and end_arret - start_arret >= 1800)\ or (start_ts <= start_arret <= end_ts and type == "Imprévu" and end_arret - start_arret >= limit_imprevu): count += 1 return count > 10 while count_valid_arret(arrets, limit_imprevu): limit_imprevu += 10 for arret in arrets: container_arret = QVBoxLayout() container_arret.setSpacing(0) start_arret = arret[0] end_arret = arret[1] type = arret[2][0].type if arret[2] else "non renseigné" if (start_ts <= start_arret <= end_ts and end_arret - start_arret >= 1800) \ or (start_ts <= start_arret <= end_ts and type == "Imprévu" and end_arret - start_arret >= limit_imprevu): start = str(timestamp_to_hour_little(start_arret)) duree = str(timedelta(seconds=round(end_arret - start_arret))) text_arret = "Arrêt {type} à {start}, durée {duree}".format(type=type, start=start, duree=duree) if type == "Imprévu" or type == "non renseigné": stylesheet = red_12_bold_label_stylesheet else: stylesheet = blue_12_bold_label_stylesheet title_arret = QLabel(text_arret) title_arret.setStyleSheet(stylesheet) container_arret.addWidget(title_arret, alignment=Qt.AlignTop) def add_label_to_container(vbox, label): label.setStyleSheet(black_12_label_stylesheet) label.setWordWrap(True) vbox.addWidget(label, alignment=Qt.AlignTop) vbox.addLayout(container_arret) if arret[2]: if type == "Imprévu": for raison in arret[2]: if raison.type == "Nettoyage" or raison.type == "Prévu": continue add_label_to_container(container_arret, QLabel(raison.raison)) else: add_label_to_container(container_arret, QLabel(arret[2][0].raison)) else: add_label_to_container(container_arret, QLabel("")) vbox.addLayout(container_arret) vbox.addStretch(1) return vbox
def get_drawing_info(self): timestamp = timestamp_at_day_ago(settings_store.day_ago) debut = timestamp_at_time(timestamp, hours=chart_min_hour) fin = timestamp_at_time(timestamp, hours=chart_max_hour) ech = (fin - debut) / (settings_store.zoom * self.get_chart_width()) return debut, fin, ech
def update_data_metrage(): """ Donnee enregistree de maniere fiable depuis le 23/10/2017 semaine 43 (timestamp: 1508709600) Fonction appele a chaque demarrage de l'application Parcour tout les jours depuis le 23/10/2017 jusqu'a hier Verifie si les donnees metrages de chaque jour est renseigne en base de donnee Si les donnees metrages n'existes pas on les calculs et on les inserts en base de donnee """ def get_jour_metrage(): """ Recupere les jours ou les metrages sont deja renseignees en base de donnee :return: Une liste des jours """ list_jour_metrage = Database.get_all_jour_metrages() clean_list = [] for jour_metrage in list_jour_metrage: ts = jour_metrage[0] clean_list.append(ts) return clean_list def is_vendredi(ts): """ Test si le jour d'un timestamp est vendredi :param ts: L etimestamp a tester :return: True si on est vendredi """ return timestamp_to_day(ts) == "vendredi" def get_metrage(data, vendredi): """ Calcul les metrages de l'equipe du matin et du soir Prend en compte si on est vendredi :param data: Les donnees triees par seconde :param vendredi: True si on traite des donnees d'un vendredi :return: Les valeurs arrondies du metrage matin et soir """ metrage_matin = 0 metrage_soir = 0 fin_prod_matin = FIN_PROD_MATIN_VENDREDI if vendredi else FIN_PROD_MATIN for value in data: ts = value[0] metrage = value[1] / 60 if value[1] > 0 else 0 if ts < timestamp_at_time(ts, hours=fin_prod_matin): metrage_matin += metrage else: metrage_soir += metrage return round(metrage_matin), round(metrage_soir) # On recupere la liste des jours ou le metrage est renseigne en base de donnee list_jour_metrage_on_db = get_jour_metrage() # Debut des donnees fiable start_data_record = 1508709600 # Duree d'un jour en ms ts_to_one_day = 86400 # Timestamp du debut du jour actuel start_ts_of_current_day = timestamp_at_day_ago(day_ago=0) start_day = start_data_record while start_day < start_ts_of_current_day: if start_day in list_jour_metrage_on_db: pass else: start_time = timestamp_at_time(ts=start_day, hours=DEBUT_PROD_MATIN) end_time = timestamp_at_time(start_day, hours=FIN_PROD_SOIR) speed_data = Database.get_speeds(start_time=start_time * 1000, end_time=end_time * 1000) clean_speed_data = clean_data_per_second(speed_data, start_time, end_time) total_metrage = get_metrage(data=clean_speed_data, vendredi=is_vendredi(start_day)) Database.insert_jour_metrages(ts_jour=start_day, metrage_matin=total_metrage[0], metrage_soir=total_metrage[1]) start_day = timestamp_after_day_ago(start_day, day_ago=1) return True
def get_timestamp_at_time(hours, p_min): ts_at_day_ago = timestamp_at_day_ago(settings_store_gestion.day_ago) ts = timestamp_at_time(ts=ts_at_day_ago, hours=hours, min=p_min) return ts