1
- import asyncio
2
1
import json
3
- import pydantic
4
2
import logging
5
-
3
+ import asyncio
4
+ import pydantic
5
+ from os import environ
6
6
from pydantic import ValidationError
7
7
from sqlalchemy import MetaData
8
8
from sqlalchemy .orm import Session
9
9
from sqlalchemy import create_engine
10
10
from sqlalchemy .ext .declarative import declarative_base
11
- from os import environ
12
11
from firebase_admin import messaging
13
12
14
13
from external .Users import UsersService
15
14
from ..common .middleware import Middleware
16
15
from database .models .measurement import Measurement
17
16
from database .database import SQLAlchemyClient
18
- from resources .parser import apply_rules
17
+ from resources .parser_rules import apply_rules
19
18
from schemas .measurement import MeasurementReadingSchema
19
+ from resources .parser_messages import parse_message
20
20
from exceptions .logger_messages import LoggerMessages
21
21
from exceptions .invalid_insertion import InvalidInsertionError
22
22
from exceptions .deviating_parameters import DeviatedParametersError
25
25
26
26
27
27
Base = declarative_base (
28
- metadata = MetaData (schema = environ .get ("POSTGRES_SCHEMA" , "measurements_service" ))
28
+ metadata = MetaData (
29
+ schema = environ .get ("POSTGRES_SCHEMA" , "measurements_service" )
30
+ )
29
31
)
30
32
logger = logging .getLogger ("rabbitmq_consumer" )
31
- logging .getLogger ("pika" ).setLevel (logging .WARNING )
32
33
dbUrl = environ .get ("DATABASE_URL" ).replace ("postgres://" , "postgresql://" , 1 )
33
34
engine = create_engine (dbUrl , echo = True , future = True )
34
35
session = Session (engine )
35
36
36
-
37
37
class Consumer :
38
- def __init__ (self , queue_name ):
39
- self .__queue_name = queue_name
38
+ def __init__ (self , topic ):
40
39
self .__middleware = Middleware ()
41
40
self .__sqlAlchemyClient = SQLAlchemyClient ()
42
41
self .__users = UsersService ()
42
+ self .__last_measurements = {}
43
+ self .__topic = topic
43
44
44
45
def run (self ):
45
- self .__middleware .create_queue (self .__queue_name )
46
- self .__middleware .listen_on (self .__queue_name , self .__callback )
46
+ self .__middleware .listen_on (self .__callback , self .__topic )
47
+ self .__middleware .connect ()
48
+ self .__middleware .run ()
47
49
48
50
def obtain_device_plant (self , measurement_from_rabbit ):
49
51
try :
@@ -54,12 +56,13 @@ def obtain_device_plant(self, measurement_from_rabbit):
54
56
return dp
55
57
except Exception as err :
56
58
logger .error (f"{ err } - { type (err )} " )
57
- raise RowNotFoundError (measurement_from_rabbit .id_device , "DEVICE_PLANT" )
59
+ raise RowNotFoundError (measurement_from_rabbit .id_device ,
60
+ "DEVICE_PLANT" )
58
61
59
62
async def obtain_user (self , user_id ):
60
63
return await self .__users .get_user (user_id )
61
64
62
- def check_package (self , measurement ):
65
+ def check_package (self , measurement : MeasurementReadingSchema ):
63
66
empty_values = []
64
67
if measurement .temperature is None :
65
68
empty_values .append ("temperature" )
@@ -70,7 +73,9 @@ def check_package(self, measurement):
70
73
if measurement .light is None :
71
74
empty_values .append ("light" )
72
75
73
- if measurement .humidity is None :
76
+ # Nuestro sensor no mide humedad del ambiente!
77
+ if measurement .humidity is None and not measurement .id_device .\
78
+ startswith ("sensor_" ):
74
79
empty_values .append ("humidity" )
75
80
76
81
if measurement .id_device is None :
@@ -113,24 +118,24 @@ def generate_notification_body(self, error):
113
118
async def send_notification (self , id_user , measurement , error , details ):
114
119
device_plant = self .obtain_device_plant (measurement )
115
120
116
- user = await self .obtain_user (device_plant .id_user )
117
-
118
- notification_body = self .generate_notification_body (error )
119
-
120
121
try :
122
+ user = await self .obtain_user (device_plant .id_user )
123
+ notification_body = self .generate_notification_body (error )
121
124
if user .device_token is not None :
122
125
message = messaging .Message (
123
- notification = messaging .Notification (title = "Estado de tu planta" ,
124
- body = notification_body ),
125
- token = user .device_token )
126
+ notification = messaging .Notification (
127
+ title = "Estado de tu planta" , body = notification_body
128
+ ),
129
+ token = user .device_token ,
130
+ )
126
131
messaging .send (message )
127
132
logger .info (LoggerMessages .USER_NOTIFIED .format (id_user ))
128
133
129
134
except Exception as e :
130
135
logger .info (e )
131
136
pass
132
137
133
- def apply_rules (self , measurement , device_plant ):
138
+ def apply_rules (self , measurement : MeasurementReadingSchema , device_plant ):
134
139
deviated_parameters = apply_rules (measurement , device_plant .plant_type )
135
140
if deviated_parameters .hasDeviations ():
136
141
raise DeviatedParametersError (deviated_parameters )
@@ -156,16 +161,25 @@ def save_measurement(self, measurement_from_rabbit, device_plant):
156
161
except Exception as err :
157
162
logger .error (f"{ err } - { type (err )} " )
158
163
self .__sqlAlchemyClient .rollback ()
159
- raise InvalidInsertionError (measurement_from_rabbit , "MEAUSUREMENT" )
164
+ raise InvalidInsertionError (measurement_from_rabbit ,
165
+ "MEAUSUREMENT" )
160
166
161
- def __callback (self , body ):
167
+ def __callback (self , client , userdata , msg ):
162
168
device_plant = None
163
- measurement = None
169
+ measurement , body = parse_message (self .__last_measurements , msg )
170
+ if measurement is None :
171
+ return
172
+
173
+ # 1) flood de notificaciones !!
174
+ # 2) light!!!!
175
+ # 3) humedad! no enviamos notificacion cuando llega none...??? [OK]
176
+ # 4) convertir int a float en simulador y microservice [OK]
164
177
178
+ # 5) refactor decode_body [OK]
165
179
try :
166
- measurement = MeasurementReadingSchema (** json .loads (body ))
167
180
logger .info (
168
- LoggerMessages .NEW_PACKAGE_RECEIVED .format (measurement .id_device )
181
+ LoggerMessages .NEW_PACKAGE_RECEIVED
182
+ .format (measurement .id_device )
169
183
)
170
184
logger .debug (LoggerMessages .PACKAGE_DETAIL .format (body ))
171
185
@@ -181,7 +195,8 @@ def __callback(self, body):
181
195
logger .debug (LoggerMessages .ERROR_DETAILS .format (err , body ))
182
196
except RowNotFoundError as err :
183
197
logger .warn (
184
- LoggerMessages .ROW_NOT_FOUND .format (err .primary_key , err .name_table )
198
+ LoggerMessages .ROW_NOT_FOUND .format (err .primary_key ,
199
+ err .name_table )
185
200
)
186
201
logger .debug (LoggerMessages .ERROR_DETAILS .format (err , body ))
187
202
@@ -195,7 +210,8 @@ def __callback(self, body):
195
210
logger .warn (LoggerMessages .DEVIATING_PARAMETERS )
196
211
logger .debug (LoggerMessages .ERROR_DETAILS .format (err , body ))
197
212
198
- asyncio .run (self .send_notification (device_plant .id_user , measurement ,
213
+ asyncio .run (self .send_notification (device_plant .id_user ,
214
+ measurement ,
199
215
err , body ))
200
216
201
217
if device_plant is not None and measurement is not None :
0 commit comments