grafico.py 6.32 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import mysql.connector
import numpy as np
import matplotlib.pyplot as plt
from datetime import date
import seaborn
import time
from time import localtime
import os

'''
Programa que maneja os histogramas, faz a atualização deles com dados do mysql de um usuario específico.

Possui o mecanismo de comunicação com o site, quando ocorrer um erro irá aparecer um card vermelho no final
do site
'''
16

17
18
19
20
21
22
23
24
25
26
27
############ argumentos ############

user_sql= "bruno" # usuario do detector que serão usados os dados

output= 'graficododia.png' # nome do arquivo histograma

minutos= 30 # tamanho do bin

dormir= 2*60 # tempo que o programa dorme para acumular mais dados em segundos

Eventos= "Eventos/"+str(minutos)+"min" # titulo de y do histograma
Bruno Thomazi Zanette's avatar
Bruno Thomazi Zanette committed
28
29


30
31
############ Funções ############

32
33
34
35
36
def data_inicio_fim(): 
    '''
    Função que dá a hora do inicio e final 
    do dia atual em segundos da epoch 
    '''
37
38
    listA=list(localtime())
    listB=list(localtime())
39
40
    
    for i in range (3,6): # posições que são zero
41
        listA[i]=0 # zerando hora minuto segundo
42
        
43
        if i==3:
44
            listB[i]=23 # horas
45
        elif i==4:
46
            listB[i]=59 # min
47
        else:
48
            listB[i]=60 # seg
49
50
51
52
53
54
55
    
    datainicial = tuple(listA)
    datafinal = tuple(listB)
    
    return((time.mktime(datainicial),time.mktime(datafinal)))

def manejo_pasta(file):
56
57
58
59
60
61
    '''
    Função que leva o arquivo file para
    posição '/home/brunoz31/graficos/'

    Exemplo de nome: histograma27082021
    '''    
62
63
64
65
66
    nome=date.today().strftime("histograma%d%m%Y")
    
    os.rename(file,f'/home/brunoz31/graficos/{nome}')

def mensagem_sql(usuario, tempo):
67
68
69
70
71
    '''
    Função que retorna a mensagem de sql 
    para seleção de dados de um usuario
    que chegaram depois de um tempo 
    '''    
72
    
73
    where= tempo*1000 # em ms
74
75
76
77
78
79
80
    
    mensagem=f'select hora from eventos where hora >= {where} and usuario="{usuario}";'
    
    return(mensagem)
    
def plot_dist(data, x_label, y_label, tittle, number_bins, plot_output):
    """
Bruno Thomazi Zanette's avatar
Bruno Thomazi Zanette committed
81
82
83
84
85
86
    Args:
        data (list): List with data to be plotted.
        x_label (str): Plot x-label.
        y_label (str): Plot y-label.
        tittle (str): Plot tittle.
        number_bins (int): Number of bins for distribution.
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
        plot_output (str): Path to plot output.
    """
    plt.xlim([0, 24])
    
    seaborn.set(color_codes='dark')
    seaborn.set_style("white")
    plt.figure(1, figsize=(9, 6))
    plt.xticks(np.arange(0, 25, 1.0))
    sns_plot = seaborn.histplot(data, bins=number_bins, color="#5881C1")
    sns_plot.set(xlabel=x_label, ylabel=y_label)
    plt.title(tittle) 
    sns_plot.figure.savefig(plot_output, bbox_inches='tight', dpi=400)
    plt.show()
    plt.close()

102
def troca_texto(nomefile,outword, inword):
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    '''
    Programa que recebe um arquivo e substitui uma palavra por outra
    e escreve novamente no arquivo
    
    Args:
        nomefile (str): nome do arquivo que será modificado
        outword (str): palavra que será procurada no arquivo para ser substituida
        inword (str): pela pela qual a outword será substituida    
    '''
    with open(nomefile,"r") as arquivo: #abre sem apagar o arquivo
        lido = arquivo.read() # lê o arquivo armazenado em nomefile
        
        mudado = lido.replace(outword,inword) #troca a str em outword pelo str em inword
        
    with open(nomefile,"w") as arqu: #apaga texto do arquivo
        arqu.write(mudado) # escreve novo com as palavras trocadas

120
121
122
123
124
125
def erro(html): 
    '''
    Função que encontra o erro tem que ser atualizado no html

    toda vez que muda o html tem que mudar a posição 10584:-25
    '''
126
127
128
    with open(html,"r") as arquivo: #abre sem apagar o arquivo
        lido = arquivo.read() # lê o arquivo armazenado em nomefile
        string_erro = lido[10584:-25]
129
        
130
131
132
133
134
        return(string_erro)

############ loop principal ############

endereco_html = "/var/www/html/testou.html"
135
136
troca_texto(endereco_html,"verme","verde")
troca_texto(endereco_html,erro(endereco_html),"ok")
137

138
tempo_inicial , tempo_final= data_inicio_fim() #começo e fim do dia que o programa rodou
139
140

tempo_sql = tempo_inicial # para que haja seleção de dados antes da meia noite anterior
141

142
143
144
145
146
147
148
try:
    while True:

        ##### troca de dia #####    

        if time.time() > tempo_final: 
            manejo_pasta(output)# manda o histograma para a pasta graficos quando passa da meia noite
149
            tempo_inicial , tempo_final= data_inicio_fim() #novo tempo inical e final
150
151
152
153
154
155
            tempo_sql = tempo_inicial # tempo utilizado para consulta sql atualizado
        
        ##### Recebe os dados #####
        
        db_connection = mysql.connector.connect( # Conectando ao sql
          host='localhost',
Bruno Thomazi Zanette's avatar
Bruno Thomazi Zanette committed
156
          user='user',
157
          passwd='password', 
158
159
160
161
162
          auth_plugin='mysql_native_password'
        )
        cur = db_connection.cursor() # Create a Cursor object to execute queries.

        cur.execute("USE COSMICPAMPA;") # Seleciona banco de dados previamento criado a ser usado.
163
        mensagem = mensagem_sql(user_sql,tempo_sql) # comando sql que será executado        
164
165
166
167
        cur.execute(mensagem) # executa o comando sql

        dados = np.array([],dtype=float) # vetor que armazena os dados em ms

168
        for row in cur.fetchall(): # coloca os dados de tempo do mysql no array dados           
169
170
            dados= np.append(dados,row)
        
171
172
173
174
175
        if dados.size > 0: # se houver 
            extensaodehoras = (dados[-1] - dados[0])/(1000*60*60) # usado para que o número de bins creçam conforme a chegada de mais dados

            for i in range(0,len(dados)):       
                dados[i]= (dados[i] - tempo_inicial*1000)/(1000*60*60) # transformando os dados em horas
176
        
177
178
179
180
        else:
            dados= np.append(dados,-10)
            extensaodehoras = (dados[-1] - dados[0])/(1000*60*60)

181
182
183
184
        ##### histograma #####

        today = date.today()# Data para o título
        d1 = today.strftime("%A %d/%b/%Y")
185
186
        bins=round(extensaodehoras)*2

187
188
189
190
191
192
193
194
195
        if bins < 1: # para garantir que haja sempre pelo menos um bin
            bins=1
        
        plot_dist(dados, "Horas", Eventos, d1, bins, output)

        # pausa de 1 minutos no loop para chegar novos dados
        time.sleep(dormir)

except Exception as e:    
196
197
198
    troca_texto(endereco_html,"verde","verme")
    troca_texto(endereco_html,"ok",f"O erro foi {e} no programa grafico.py")