from rest_framework import viewsets from rest_framework.decorators import action from django.http import JsonResponse from django.db.models import F from django.db import connection from django_filters.rest_framework import DjangoFilterBackend from api import models, serializers from os import getenv import redis import json import logging # funcion para registrar en mongo from logger.views import save_log_dispositivo class DispositivoViewSet(viewsets.ModelViewSet): queryset = models.Dispositivo.objects.all() serializer_class = serializers.DispositivoSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['id_dispositivo', 'id_paradero', 'id_tipo_dispositivo'] @action(detail=False, methods=['post']) def whoami(self, request, pk=None): input = json.loads(request.body) whoami = input['whoami'] record = models.Paradero.objects \ .filter(dispositivo__id_dispositivo=whoami['idDispositivo']) \ .annotate(nro_paradero=F('id_paradero'), nombre_paradero=F('stop_name')) \ .first() if (record): save_log_dispositivo(id_dispositivo=whoami['idDispositivo'], accion_url='whoami') return JsonResponse({ "WhoamiResponse": { "NroParadero": record.nro_paradero, "NombreParadero": record.nombre_paradero, "Status": "OK" } }) # retorna json de no existente return JsonResponse({ "WhoamiResponse": { "Status": "NOK", "errorString": "Dispositivo no identificado" } }) @action(detail=False, methods=['post','get']) def getInfoDevice(self, request, pk=None): input = json.loads(request.body) getInfoDevice = input['GetInfoDevice'] cursor = connection.cursor() paradero = models.Paradero.objects \ .filter(dispositivo__id_dispositivo=getInfoDevice['idDispositivo']) \ .annotate(nro_paradero=F('id_paradero'), nombre_paradero=F('stop_name')) \ .first() db_host = getenv('DB_REDIS_HOST') db_port = getenv('DB_REDIS_PORT') r = redis.Redis(host=db_host, port=db_port, decode_responses=True) key = f'stop_id:{paradero.nro_paradero}' json_trayectos = r.get(key) trayectos = [] if json_trayectos != None: trayectos = json.loads(json_trayectos) key = f'stop_id:none' json_trayectos = r.get(key) trayectos_none = [] if json_trayectos != None: trayectos_none = json.loads(json_trayectos) # agregar al listado los trayecto en donde no se registro el paradero """ json_trayectos = r.get('stop_id:none') trayectos_none = [] if json_trayectos != None: trayectos_none = json.loads(json_trayectos) for trayecto in trayectos_none: trayecto['stop_id'] = 'none' trayecto['hora_llegada'] = None trayectos.append(trayecto) """ lineas = models.Linea.objects.filter(lineaparadero__id_paradero = paradero.id_paradero).order_by('route_short_name') detalle_lineas = [] for linea in lineas: llegadas = [] for trayecto in trayectos: id_linea = f"{trayecto['route_id']}-{trayecto['direction_id']}" stop_id = trayecto['stop_id'] patente = trayecto['vehicle_license_plate'] trayecto['stop_id_alterno'] = None if id_linea == linea.id_linea: hora_llegada = trayecto['hora_llegada'] distancia_km = None # si no trae latitud ni longitud: buscar en trayectos_none por patente # y sobreescribir latitud y longitud if trayecto['latitude'] == 0 and trayecto['longitude'] == 0: for trayecto_none in trayectos_none: if patente == trayecto_none['vehicle_license_plate']: trayecto['longitude'] = trayecto_none['longitude'] trayecto['latitude'] = trayecto_none['latitude'] trayecto['stop_id_alterno'] = 'none' break if trayecto['latitude'] != 0 and trayecto['longitude'] != 0: trip_id = trayecto['trip_id'] velocidad_promedio = 80 p_lon = trayecto['longitude'] p_lat = trayecto['latitude'] sql = "select hora_llegada, distancia_km from fn_gtfs_calcula_distancia_tiempo_llegada(%s,%s,%s,%s,%s)" cursor.execute(sql, [trip_id, stop_id, velocidad_promedio, p_lon, p_lat]) row = cursor.fetchone() if patente == 'FDCB32': print(f'SQL: {sql}', flush=True) print(f'params: {[trip_id, stop_id, velocidad_promedio, p_lon, p_lat]}', flush=True) print(f'row: {row}', flush=True) if row != None: hora_llegada = row[0].strftime('%H:%M:%S') distancia_km = row[1] llegadas.append({ 'patente': trayecto['vehicle_license_plate'], 'Planificada': trayecto['hora_llegada'], 'Latitud': trayecto['latitude'], 'Longitud': trayecto['longitude'], 'stop_id_alterno': trayecto['stop_id_alterno'], 'EstimadaGPS': hora_llegada, 'DistanciaGPS': distancia_km, 'Mensajelinea': None, }) llegadas_ordendas = sorted(llegadas, key=lambda x: x['DistanciaGPS']) item = { 'Linea': linea.route_long_name, 'Descripcion': linea.route_short_name, 'TipoLocomocion': linea.route_type.descripcion, 'colorFondo': linea.route_color, 'colorTexto': linea.route_text_color, 'Llegadas': llegadas_ordendas } detalle_lineas.append(item) # lineas = {} # lineas_agrupadas = {} # for t in trayectos: # pk_linea = f'{t["route_id"]}-{t["direction_id"]}' # if pk_linea not in lineas: # lineas[pk_linea] = models.Linea.objects.filter(id_linea=pk_linea).first() # linea = lineas[pk_linea] # if linea == None: # print(pk_linea, flush=True) # if linea != None: # if pk_linea not in lineas_agrupadas: # lineas_agrupadas[pk_linea] = { # 'Linea': linea.route_long_name, # 'Descripcion': linea.route_short_name, # 'TipoLocomocion': linea.route_type.descripcion, # 'colorFondo': linea.route_color, # 'colorTexto': linea.route_text_color, # 'Llegadas': [] # } # sql = "select hora_llegada, distancia_km from fn_gtfs_calcula_distancia_tiempo_llegada(%s,%s,%s,%s,%s)" # trip_id = t['trip_id'] # paradero_id = t['stop_id'] # velocidad_promedio = 30 # p_lon = t['longitude'] # p_lat = t['latitude'] # cursor.execute(sql, [trip_id, paradero_id, velocidad_promedio, p_lon, p_lat]) # row = cursor.fetchone() # hora_llegada = None # distancia_km = None # if row != None: # hora_llegada = row[0].strftime('%H:%M:%S') # distancia_km = row[1] # lineas_agrupadas[pk_linea]['Llegadas'].append({ # 'patente': t['vehicle_license_plate'], # 'Planificada': t['hora_llegada'], # 'EstimadaGPS': hora_llegada, # 'DistanciaGPS': distancia_km, # 'Mensajelinea': None, # }) # detalle_lineas = [] # for pk_linea in lineas_agrupadas: # detalle_lineas.append(lineas_agrupadas[pk_linea]) save_log_dispositivo(id_dispositivo=getInfoDevice['idDispositivo'], accion_url='getInfoDevice') cursor.close() return JsonResponse({ "GetInfoDeviceResponse": { "DetalleLineas": detalle_lineas, "MensajeParadero": "No considerar, uso futuro", "NroParadero": paradero.nro_paradero, "NombreParadero": paradero.nombre_paradero, "proto": trayectos, } })