inicial.py 6.92 KB
Newer Older
Bruno Thomazi Zanette's avatar
Bruno Thomazi Zanette committed
1
2
#!/usr/bin/env python3

3
'''
4
5
6
7
8
9
10
11
12
Programa que roda até ser encerrado (ctrl+c) checando por erros as mensagens recebidas 
pelo tópico "cosmic" por mqtt e salvando-as na database COSMICPAMPA tabela eventos

A saúde do programa pode ser checada por:

* Arquivo log: cat log_inicial.dat
* Tópico mqtt feedback: mosquitto_sub -h localhost -t feedback -P cta -u cta
* Flag no site: http://sandbox.cosmicpampa.cc/testou.html 
    * Ela ficará vermelha caso o programa pare de funcionar
13
'''
14
15
16
17

import paho.mqtt.client as mqtt 
import hashlib 
import mysql.connector
18
from datetime import datetime
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
############ argumentos ############

global cur

endereco_html = "/var/www/html/testou.html"

broker_address="localhost"
topico= "cosmic" #Topico mqtt
username_MQTT="cta" #user para MQTT
password_MQTT="cta" #senha para MQTT

output= 'log_inicial.dat' #Arquivo log

user_db = 'user'
password_db = 'password'

36
37
############ funções ############

38
39
40
def check_usuario():
    cur.execute("USE COSMICPAMPA;")
    cur.execute('select user from usuarios;')
41
42
    
    return(cur.fetchall())
43

44
def insere_bd(colunas,valores):
45
	cur.execute("USE COSMICPAMPA;")
46
47
48
49
	cur.execute("INSERT INTO eventos ({}) VALUES({})".format(colunas,valores)) #Salva comando no cursor
    
def on_message(client, userdata, message): # Funcao que roda toda vez que se recebe uma mensagem
    
50
51
    #### mensagens no terminal (opcional)
    
52
53
    # print("message received " ,str(message.payload.decode("utf-8"))) #imprime msg no terminal
    # print("message topic=",message.topic) # imprime tópico
54
55
    # print("message qos=",message.qos)
    # print("message retain flag=",message.retain)
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    
    # colocando dados em variaveis que representam as grandezas medidas
    pre_dados = str(message.payload.decode("utf-8"))  # transforma a mensagem recebida em string
    dados = list(pre_dados.split(" ")) # separando string que chegou em uma lista por espaços 
    
    hora= float(dados[0])
    loca= "'{}'".format(dados[1])
    inte= float(dados[2])
    temp= float(dados[3])
    umid= float(dados[4])
    pres= float(dados[5])
    usua= "'{}'".format(dados[6])
    hash= "'{}'".format(dados[7])
    
    # começo das strings colunas e valores, desta forma só se salva no bd o que está correto
71
72
    colunas="hora,local"
    valores= str(hora)+","+str(loca)
73
    
74
75
76
77
78
79
80
    today = datetime.now()
    hoje = " " + today.strftime("%Y|%m|%d %H:%M:%S")
    
    # Checa o usuario
    usuarios_cadastrados = check_usuario()
    for x in usuarios_cadastrados:
        usuario_comparacao= str(usua)[1:-1]
81
82
83
84
85
86
87
88
89
90
91
        cadastrado_bool = False
        
        cadastrado_bool = usuario_comparacao == str(x)[2:-3]
        
        if cadastrado_bool:
            break 
        
    if not cadastrado_bool:
        mensag = "usuario não cadastrado: "+usua        

        print( mensag+ str(hoje),file = open(output,'a'))        
92
        client.publish("feedback", mensag)
93

94
    # Checa o Hash
95
    string = str(hora)+str(loca)[1:-1]+str(inte)+str(temp)+str(umid)+str(pres)+usua[1:-1]
96
    result = hashlib.md5(string.encode())     
97

98
99
100
    hash2 = result.hexdigest() 
    hash1= "{}".format(dados[7]) # hash específico para comparação, sem ''
    
101
    if (hash2==hash1 and cadastrado_bool): # só manda para o BD se o HASH for igual        
102
        client.publish("feedback","dadosHASH confere")
103

104
        # intensidade > 0
105
        if (inte<0): 
106
            mensag = "intensidade menor que zero"
107

108
109
            print( mensag+str(hoje),file = open(output,'a'))
            client.publish("feedback",mensag)
110

111
112
113
114
        else:
            colunas += ",intensidade"
            valores += "," + str(inte)

115
116
        # Checa se temp está entre o zero absoluto e um número grande para todas escalas (C° K F°)
        if (-274>temp or umid>1000):
117
            mensag = "temperatura errada"
118
 
119
120
            print( mensag+str(hoje),file = open(output,'a'))
            client.publish("feedback",mensag)
121
 
122
123
124
125
126
127
        else:
            colunas += ",temperatura"
            valores += "," + str(temp)
            
        # Checa se umidade está entre 0% e 100%
        if (0>umid or umid>100):
128
            mensag= "umidade errada"
129
 
130
131
            print( mensag+str(hoje),file = open(output,'a'))
            client.publish("feedback",mensag)
132
 
133
134
135
        else:
            colunas += ",umidade"
            valores += "," + str(umid)
136
        
137
138
        # Pressao > 0
        if (pres<=0):
139
            mensag = "pressao menor que zero"
140
 
141
142
            print( mensag+str(hoje),file = open(output,'a'))
            client.publish("feedback",mensag)
143
 
144
145
146
        else:
            colunas += ",pressao"
            valores += "," + str(pres)
147
148
    
    	# add valores faltam
149
150
151
152
153
        colunas += ",usuario,HASH"
        valores += ","+usua+","+hash
        
        ## Inserção no banco de dados
        
154
        insere_bd(colunas,valores) #chama a função que INSERT no banco de dados	
155
156
        db_connection.commit() # executa o comando do curso

157
    elif(cadastrado_bool): #caso hash não confira
158
        mensag = "HASH diferentes hash1: "+hash1+"hash2: "+hash2
159
  
160
161
        print( mensag+str(hoje),file = open(output,'a'))
        client.publish("feedback", mensag)
162

163
def troca_texto(nomefile,outword, inword):
164
165
166
167
168
169
170
171
172
173
    '''
    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
174
        lido = arquivo.read() # lê o arquivo armazenado em nomefile        
175
176
177
178
179
180
181
182
183
184
        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

def erro(html): # func 
    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]

185
        return(string_erro)
186

187
# Programa principal
188
try:
189
190
191
    
    troca_texto(endereco_html,"verme","verde")
    troca_texto(endereco_html,erro(endereco_html),"ok")
192
193
194
195

    db_connection = mysql.connector.connect(host='localhost',user = user_db, passwd = password_db, auth_plugin='mysql_native_password')

    cur = db_connection.cursor()
196
    
197
198
############ Subscribe ao tópico ############

199
    client = mqtt.Client("P1") #create new instance
200

201
    client.on_message = on_message #attach function to callback
202

203
    client.username_pw_set(username_MQTT, password_MQTT) # passa o user e senha do mqtt
204

205
    client.connect(broker_address) #connect to broker
206

207
    client.subscribe(topico) # se inscreve no tópico (quando chega mensagem chama a função on_message)
208

209
    client.loop_forever() # repete tudo relacionado ao mqtt
210

211
except Exception as e:    
212
213
214
215
216
    troca_texto(endereco_html,"verde","verme")
    troca_texto(endereco_html,"ok",f"O erro foi {e} no programa inicial.py")