Clima
Clima
Base de datos
- registros_climaticos: se registra los datos por estancia y fecha. si id_usuario es null la informacion se obtuvo del proveedor de clima(Cabure), la api devolvera solo un dato por dia la prioridad es el cargado por el usuario
- trazabilidad_registros_climaticos: de que nodo se saco la informacion (proveedor, id_nodo, distancia a la coordeneda consultada)
- precipitaciones_historicas
Apis
GET /api/weather/forecast
Se migro a un nuevo microservicio, solo esta para que mobile pueda seguir consultando. Hace una request al nuevo microservicio
GET /api/weather/rainfall
Permisos
- provider_data = 115 Si devuelve los datos cabure
- user_data = 113 para ver la inforcion cargada por usuarios
- historical_data = 114 registro historico
params
- farm o farm_uuid: int o uuid *obligatorio uno
- date_from ("%Y-%m-%d") default=hoy-365
- date_to ("%Y-%m-%d") default=hoy
resp
{
"daily": {
"date": {
"hail": Bool,
"irrigation": Bool,
"rainfall": Float,
"user_data": Bool,
}
},
"historical": [], // array de float, 12 posiciones una por cada mes
"monthly": {
"anio": {
"mes(int)": float, //precipitaciones del mes
}
},
"provider": {
"distance": float, // distancia promedio a todos los nodos de donde se saco informacion
"quality": str, // 'GOOD' if distance<20 else 'BAD'
}
}
Si no hay registro historico en la base de datos lo consulta en s3 con hilos para no bloquear mientras busca el registro climatico.
Busca informacion en Cabure para guardar en la base de datos, busca la ultima fecha donde tenes datos para actualizar desde la misma hasta hoy, el dato de hoy puede ser no definitivo ya que falta mediciones del dia, la proxima vez que se ingrese volvera a consultar por la ultima fecha.
Si actualizaste hace menos de 3 dias no vuelve actualizar
POST /api/weather/rainfall
params
- date *
- farm o farm_uuid *
- hail
- humidity
- irrigation
- pressure
- rainfall
- temperature
- wind_intensity
- wind_direction
PATCH /api/weather/rainfall
params
- date *
- farm o farm_uuid *
- hail
- humidity
- irrigation
- pressure
- rainfall
- temperature
- wind_intensity
- wind_direction
DELETE /api/weather/rainfall
Elimina registros creados por usurios
params
- date *
- farm o farm_uuid *
GET /api/weather/rainfall/historical
retorna lista con las precipitacoines historicas, igual que la api /api/weather/rainfall si no estan guardadas en la base de datos busca en s3
Task
historical
@application.task(
bind=True, name="tasks.weather.get_historical_rainfall_data", serializer="pickle"
)
task_get_historical_rainfall_data(self, farm, lat, lon)
Actualiza precipitaciones historicas
Registro climatico
@application.task(
bind=True, name="tasks.weather.update_provider_rainfall_data", serializer="pickle"
)
def task_update_provider_rainfall_data(
self, farm, lat, lon, update=False, date_from=None, date_to=None, user_id=None
):
Si se pasa fecha actualiza la informacion de ese rango, en caso de tener informacion actualiza.
Si no y update=True, busca la ultima fecha que tenes registro y actualizar hasta hoy. Si actualizaste en los ultimos 3 dias no lo vuelve a realizar.
Si no cumple estas condiciones actualiza los ultimos 30 dias
@application.task(bind=True, name="tasks.weather.rainfall_cache", serializer="pickle")
def task_update_rainfall_cache(self):
cron para actualizar de forma masiva, [2024-01-31] esta configurado para nuseed. aunque esta desactivado
Creacion de campo
Cuando se crea un campo si el usuario tiene los permisos se ejecutan las tareas en celery.
- task_get_historical_rainfall_data
- task_update_provider_rainfall_data, no se pasa fechas ni update, por lo tanto busca los ultimos 29 dias.
Cabure
Se utiliza la api node/get_daily_data/{lat:.4f}/{lon:.4f}/user/{user}/?date_from={date_from}&date_to={date_to}&page={page}&amount={amount}&user_permissions={user_permissions} para obtener el resumen diario.
- user_permissions en caso de estar consultando fechas de los ultimos 30 dias es free, si se buscan fechas mas viejas advanced
- El rango de fechas es de 365 dias, si se manda una rango de fechas mayor, lo divide en request de 365 dias.
Por cada request que se realiza se crea un evento en la base datos las keys son cabure_login, cabure_daily_data
SQLs para monitorear el consumo y posibles error
-- Pegadas a login
select fecha::date, count(id) AS cant_login
from events e
WHERE id_key =148
GROUP BY fecha::date
ORDER BY fecha::date
;
-- Pegadas get daily data
SELECT fecha::date,
count(id) filter(WHERE ("data"->>'user_permissions') = 'free') AS cant_free,
count(id) filter(WHERE ("data"->>'user_permissions') = 'advanced') AS cant_advanced,
count(id) AS total
from events e
WHERE id_key =149
GROUP BY fecha::date
ORDER BY fecha::date;
-- no_data, por algun motivo get_daily_data no devuelve info si pasa hay que revisar con cabure
SELECT fecha::date,
count(id) AS cant_no_data
from events e
WHERE id_key =149 AND "data"->>'code' = 'no_data'
GROUP BY fecha::date
ORDER BY fecha::date;
-- timeout, tiene un timeout de 30seg para responder cabure, analizar si hay que hacerlo async
SELECT fecha::date,
count(id) AS cant_timeout
from events e
WHERE id_key =149 AND "data"->>'error' = 'timeout'
GROUP BY fecha::date
ORDER BY fecha::date;
-- cantidad de errores, no timeout (VER PORQUE FALLAN)
SELECT fecha::date,
count(id) AS cant_no_data
from events e
WHERE id_key =149 AND "data"->>'code' = 'failed' AND "data"->>'error' <> 'timeout'
GROUP BY fecha::date
ORDER BY fecha::date;