예제 #1
0
        public async Task Run(
            [ServiceBusTrigger("plate-read", "check-vignette", Connection = "SECCTRL_RECEIVE_PLATE_READ")] PlateRead plate,
            ILogger log)
        {
            log.LogInformation($"Start vignette check for {plate.LicensePlate}");
            var car = await storage.GetCarByLicensePlateAsync(plate.Nationality, plate.LicensePlate);

            if (car != null)
            {
                if (car.Vignettes == null || !car.Vignettes.Any(v => plate.ReadTimestamp >= v.From && plate.ReadTimestamp <= v.Until))
                {
                    log.LogInformation("Vignett violatation detected");
                    if (car.Violations == null)
                    {
                        car.Violations = new List <Violation>();
                    }

                    car.Violations.Add(new Violation(plate.ReadTimestamp, "Driving without vignette"));
                    await storage.UpdateCarAsync(car);
                }
            }
            else
            {
                log.LogWarning("Car could not be found in DB");
                // TODO: Handle unknown car; out of scope for this example
            }
        }
예제 #2
0
        public static async Task Run(
            [ServiceBusTrigger("plate-read", "section-control", Connection = "SECCTRL_RECEIVE_PLATE_READ")] PlateRead plate,
            ILogger log,
            [Inject(typeof(IStorage))] IStorage storage)
        {
            log.LogInformation($"Start section control check for {plate.LicensePlate}");

            // Get car and camera from DB
            log.LogInformation($"Get car and camera data from database");
            var car = await storage.GetCarByLicensePlateAsync(plate.Nationality, plate.LicensePlate);

            var camera = await storage.GetCameraByIDAsync(plate.CameraID);

            if (camera.Start != null)
            {
                // License plate read is from a start of a section control
                log.LogInformation("Processing entry into section control");

                if (car.ActiveSection != null)
                {
                    car.Violations.Add(new Violation(plate.ReadTimestamp, "Possible fraud, entered multiple times"));
                }
                else
                {
                    car.ActiveSection = new Enter {
                        StartCameraID = camera.ID, Timestamp = plate.ReadTimestamp
                    };
                }
            }
            else if (camera.End != null)
            {
                // License plate read is from an end of a section control
                log.LogInformation("Processing exit from section control");

                if (car.ActiveSection == null)
                {
                    car.Violations.Add(new Violation(plate.ReadTimestamp, "Possible fraud, exit without enter"));
                }
                else if (camera.End.StartCameraID != car.ActiveSection.StartCameraID)
                {
                    car.Violations.Add(new Violation(plate.ReadTimestamp, "Possible fraud, exit and start do not belong th the same section control"));
                }
                else
                {
                    var averageSpeed = ((double)camera.End.DistanceFromStart) / 1000 / TimeSpan.FromTicks(plate.ReadTimestamp - car.ActiveSection.Timestamp).TotalHours;
                    if (averageSpeed > camera.End.MaximumAverageSpeed * 1.1d)
                    {
                        car.Violations.Add(new Violation(plate.ReadTimestamp, "Too fast"));
                    }

                    car.ActiveSection = null;
                }
            }

            await storage.UpdateCarAsync(car);
        }
예제 #3
0
        public Task SetMatch(string id, [FromBody] PlateRead read)
        {
            var entry = _cache.Get(id) as IEnumerable <PlateRead>;

            foreach (var r in entry)
            {
                if (r.TransactionId.Equals(read.TransactionId))
                {
                    r.Match = PlateMatch.Match;
                }
                else
                {
                    r.Match = PlateMatch.Unmatch;
                }
            }
            return(Task.FromResult(entry));
        }
예제 #4
0
        public override async Task Start(StartRequest request, IServerStreamWriter <StartResponse> responseStream, ServerCallContext context)
        {
            logger.LogInformation("Эксперимент начинается");
            var rand = new Random(42);

            for (int i = 1; i <= request.CycleCount; ++i)
            {
                logger.LogInformation($"Отправка цикла {i}");
                var plate = new PlateRead {
                    ExperimentalData = $"Эксперимент {request.ExperimentName}, шаг {i} из {request.CycleCount}: {rand.Next(100, 500000)}"
                };
                await responseStream.WriteAsync(new StartResponse { CycleNumber = i, Plate = plate });

                var status = new StatusMessage {
                    PlateTemperature = rand.Next(25, 95)
                };
                await responseStream.WriteAsync(new StartResponse { CycleNumber = i, Status = status });

                await Task.Delay(500);
            }
            logger.LogInformation("Эксперимент завершен");
        }
예제 #5
0
        public async Task Run(
            [ServiceBusTrigger("plate-read", "check-vignette", Connection = "SECCTRL_RECEIVE_PLATE_READ")] PlateRead plate,
            [SignalR(HubName = nameof(RealTimeUIHub))] IAsyncCollector <SignalRMessage> signalRMessages,
            ILogger log)
        {
            log.LogInformation($"Start vignette check for {plate.LicensePlate}");
            var car = await storage.GetCarByLicensePlateAsync(plate.Nationality, plate.LicensePlate);

            if (car != null)
            {
                if (car.Vignettes == null || !car.Vignettes.Any(v => plate.ReadTimestamp >= v.From && plate.ReadTimestamp <= v.Until))
                {
                    log.LogInformation("Vignett violatation detected");
                    if (car.Violations == null)
                    {
                        car.Violations = new List <Violation>();
                    }

                    car.Violations.Add(new Violation(plate.ReadTimestamp, "Driving without vignette"));
                    await storage.UpdateCarAsync(car);

                    await signalRMessages.AddAsync(new SignalRMessage
                    {
                        Target    = "vignetteViolation",
                        Arguments = new [] { new
                                             {
                                                 car.Nationality,
                                                 car.LicensePlate,
                                                 plate.CameraID
                                             } }
                    });
                }
            }
            else
            {
                log.LogWarning("Car could not be found in DB");
                // TODO: Handle unknown car; out of scope for this example
            }
        }
예제 #6
0
        public async Task <Message> Run(
            [BlobTrigger("car-images/cameras/{camera}/{name}", Connection = "SECCTRL_CAR_IMAGES")] CloudBlockBlob imageBlob,
            string camera,
            string name,
            ILogger log,
            [OrchestrationClient] DurableOrchestrationClient orchestrationClient)
        {
            log.LogInformation($"Start processing of new image {name} from camera {camera}");

            // Store timestamp when image was received in blob storage
            var timestamp = imageBlob.Properties.LastModified;

            // Read image file from blob storage and convert content to Base64
            log.LogInformation("Downloading image data");
            var file = new byte[imageBlob.Properties.Length];
            await imageBlob.DownloadToByteArrayAsync(file, 0);

            // Try to recognize the license plate
            log.LogInformation("Starting license plate recognition");
            var recognitionResult = await licensePlateRecognizer.RecognizeAsync(file, configuration);

            // Move image to archive
            log.LogInformation("Moving image to archive folder");
            var archiveImageId = Guid.NewGuid().ToString();
            var archiveBlob    = imageBlob.Container.GetBlockBlobReference($"archive/{archiveImageId}.jpg");
            await archiveBlob.StartCopyAsync(imageBlob);

            await imageBlob.DeleteAsync();

            log.LogInformation("Building plate read result");
            if (recognitionResult != null)
            {
                // We have recognized a license plate
                var read = new PlateRead
                {
                    ReadTimestamp         = timestamp.Value.Ticks,
                    CameraID              = camera,
                    LicensePlate          = recognitionResult.Plate,
                    Confidence            = recognitionResult.Confidence,
                    Nationality           = recognitionResult.Region,
                    NationalityConfidence = recognitionResult.RegionConfidence,
                    ImageID = archiveImageId
                };

                var readQuality = "low";
                if (recognitionResult.Confidence >= 75d && recognitionResult.RegionConfidence >= 25d)
                {
                    readQuality = "high";
                }

                if (readQuality == "low")
                {
                    var instanceId = await orchestrationClient.StartNewAsync(
                        "OrchestrateRequestApproval",
                        new PlateReadApproval
                    {
                        Read = read
                    });

                    log.LogInformation($"Durable Function Ochestration started: {instanceId}");
                }

                return(CreateMessage(read, readQuality));
            }
            else
            {
                // No license plate found
                var read = new EmptyPlateRead
                {
                    ReadTimestamp = timestamp.Value.Ticks,
                    CameraID      = camera,
                    ImageID       = archiveImageId
                };
                return(CreateMessage(read, "empty"));
            }
        }