public async Task <TeamDto> RegisterTeam(TeamRegistrationDto team) { ValidateTeam(team); Team teamToRegister = _teamRegistrationMapper.Map(team); List <Location> availableLocations = await _dbContext.Locations.Where(x => x.Teams.Count == 0).ToListAsync(); teamToRegister.Location = availableLocations.RandomSingle(); if (teamToRegister.Location == null) { throw new Exception("No locations available"); } teamToRegister.Score = 100; teamToRegister.TotalNumberOfAndroids = 1000; teamToRegister.Password = Crypt.HashPassword(teamToRegister.Password, 10, enhancedEntropy: true); _dbContext.Teams.Add(teamToRegister); await _dbContext.SaveChangesAsync(); TeamDto registeredTeam = _teamMapper.Map(teamToRegister); registeredTeam.NumberOfAndroidsAvailable = teamToRegister.TotalNumberOfAndroids; return(registeredTeam); }
private static async Task HandleAutoFeedback() { using (HtfDbContext dbContext = new HtfDbContext()) { List <Android> androidsToAutonomouslySendData = await dbContext.Androids .Where(x => !x.Compromised && x.AutoPilot != AutoPilot.Level3).ToListAsync(); foreach (Android android in androidsToAutonomouslySendData) { SensoryDataRequest lastAutonomousDataRequest = await dbContext.SensoryDataRequests .Where(x => x.AndroidId == android.Id && x.AutonomousRequest) .OrderByDescending(o => o.TimeStamp).FirstOrDefaultAsync(); TimeSpan timeSinceLastAutonomousUpdate = DateTime.UtcNow - (lastAutonomousDataRequest?.TimeStamp ?? DateTime.MinValue); TimeSpan updateThreshold = TimeSpan.MaxValue; switch (android.AutoPilot) { case AutoPilot.Level1: updateThreshold = TimeSpan.FromMinutes(15); break; case AutoPilot.Level2: updateThreshold = TimeSpan.FromMinutes(5); break; } if (timeSinceLastAutonomousUpdate > updateThreshold) { SensoryDataRequest request = new SensoryDataRequest { AndroidId = android.Id, AutonomousRequest = true, Location = true, Crowd = true, Mood = true, Relationship = true, TimeStamp = DateTime.UtcNow }; await dbContext.SensoryDataRequests.AddAsync(request); await dbContext.SaveChangesAsync(); } } } }
/// <summary> /// Deploys a new android in the field. /// </summary> /// <param name="teamId">The unique identifier of the registered team to deploy an android for.</param> /// <param name="android">The android settings to use for deployment.</param> /// <returns>The deployed android.</returns> public async Task <AndroidDto> DeployAndroid(Guid teamId, DeployAndroidDto android) { Team teamToCheck = await _dbContext.Teams.SingleOrDefaultAsync(x => x.Id == teamId); if (teamToCheck == null) { throw new HtfValidationException("The specified team is unknown!"); } if (!Crypt.EnhancedVerify(android.Password, teamToCheck.Password)) { throw new HtfValidationException("The specified password is not correct!"); } Android androidToDeploy = _deploymentMapper.Map(android); if (!Enum.IsDefined(typeof(AutoPilot), androidToDeploy.AutoPilot)) { throw new HtfValidationException("The specified value for 'AutoPilot' is not within the expected range!"); } if (!Enum.IsDefined(typeof(SensorAccuracy), androidToDeploy.LocationSensorAccuracy)) { throw new HtfValidationException("The specified value for 'CrowdSensorAccuracy' is not within the expected range!"); } if (!Enum.IsDefined(typeof(SensorAccuracy), androidToDeploy.CrowdSensorAccuracy)) { throw new HtfValidationException("The specified value for 'LocationSensorAccuracy' is not within the expected range!"); } if (!Enum.IsDefined(typeof(SensorAccuracy), androidToDeploy.MoodSensorAccuracy)) { throw new HtfValidationException("The specified value for 'MoodSensorAccuracy' is not within the expected range!"); } if (!Enum.IsDefined(typeof(SensorAccuracy), androidToDeploy.RelationshipSensorAccuracy)) { throw new HtfValidationException("The specified value for 'RelationshipSensorAccuracy' is not within the expected range!"); } Int32 existingAndroids = await _dbContext.Androids.CountAsync( x => x.TeamId == teamId && !x.Compromised && x.AutoPilot == androidToDeploy.AutoPilot); switch (androidToDeploy.AutoPilot) { case AutoPilot.Level1: if (existingAndroids >= 500) { throw new HtfValidationException("This many level-1 androids in the field is getting suspicious!"); } break; case AutoPilot.Level2: if (existingAndroids >= 50) { throw new HtfValidationException("This many level-2 androids in the field is getting suspicious!"); } break; case AutoPilot.Level3: if (existingAndroids >= 5) { throw new HtfValidationException("This many level-3 androids in the field is getting suspicious!"); } break; } androidToDeploy.TeamId = teamId; if (androidToDeploy.AutoPilot == AutoPilot.Level1) { androidToDeploy.LocationSensorAccuracy = SensorAccuracy.LowAccuracySensor; androidToDeploy.CrowdSensorAccuracy = SensorAccuracy.LowAccuracySensor; androidToDeploy.MoodSensorAccuracy = SensorAccuracy.LowAccuracySensor; androidToDeploy.RelationshipSensorAccuracy = SensorAccuracy.LowAccuracySensor; } if (androidToDeploy.AutoPilot == AutoPilot.Level2) { androidToDeploy.LocationSensorAccuracy = SensorAccuracy.MediumAccuracySensor; androidToDeploy.CrowdSensorAccuracy = SensorAccuracy.MediumAccuracySensor; androidToDeploy.MoodSensorAccuracy = SensorAccuracy.MediumAccuracySensor; androidToDeploy.RelationshipSensorAccuracy = SensorAccuracy.MediumAccuracySensor; } switch (androidToDeploy.AutoPilot) { case AutoPilot.Level1: teamToCheck.Score += 10; break; case AutoPilot.Level2: teamToCheck.Score += 100; break; case AutoPilot.Level3: teamToCheck.Score += 1000; break; } await _dbContext.Androids.AddAsync(androidToDeploy); await _dbContext.SaveChangesAsync(); return(_androidMapper.Map(androidToDeploy)); }
private static async Task HandlePendingRequests() { using (HtfDbContext dbContext = new HtfDbContext()) { Console.WriteLine("[ HTF2017 - Getting pending sensory data requests... ]"); List <SensoryDataRequest> dataRequests = await dbContext.SensoryDataRequests .Where(x => !x.Fulfilled).OrderBy(x => x.TimeStamp).ToListAsync(); Console.WriteLine($"[ HTF2017 - {(dataRequests.Count > 0 ? $"{dataRequests.Count}" : "no")} pending sensory data requests found. ]"); foreach (SensoryDataRequest dataRequest in dataRequests) { Android android = await dbContext.Androids.Include(x => x.Team).SingleOrDefaultAsync(x => x.Id == dataRequest.AndroidId); if (android != null) { Location location = await dbContext.Locations.SingleOrDefaultAsync(x => x.Id == android.Team.LocationId); Console.WriteLine($"[ HTF2017 - Processing datarequest for '{android.Team.Name}'. ]"); SensoryData previousCrowdSensoryData = await dbContext.SensoryData .Where(x => x.AndroidId == dataRequest.AndroidId && x.Crowd.HasValue) .OrderByDescending(o => o.TimeStamp).FirstOrDefaultAsync(); SensoryData previousMoodSensoryData = await dbContext.SensoryData .Where(x => x.AndroidId == dataRequest.AndroidId && x.Mood.HasValue) .OrderByDescending(o => o.TimeStamp).FirstOrDefaultAsync(); SensoryData previousRelationshipSensoryData = await dbContext.SensoryData .Where(x => x.AndroidId == dataRequest.AndroidId && x.Relationship.HasValue) .OrderByDescending(o => o.TimeStamp).FirstOrDefaultAsync(); SensoryData data = new SensoryData { AndroidId = dataRequest.AndroidId, // https://www.movable-type.co.uk/scripts/latlong.html Longitude = dataRequest.Location ? location.Longitude : (Double?)null, Lattitude = dataRequest.Location ? location.Lattitude : (Double?)null, Crowd = dataRequest.Crowd ? GetCrowd(android, previousCrowdSensoryData) : null, Mood = dataRequest.Mood ? GetMood(android, previousMoodSensoryData) : null, Relationship = dataRequest.Relationship ? GetRelationship(android, previousRelationshipSensoryData) : null, TimeStamp = DateTime.UtcNow, AutonomousRequested = dataRequest.AutonomousRequest }; await dbContext.SensoryData.AddAsync(data); dataRequest.Fulfilled = true; Boolean isCompromised = IsAndroidCompromised(android.AutoPilot, android.LocationSensorAccuracy, android.CrowdSensorAccuracy, android.MoodSensorAccuracy, android.RelationshipSensorAccuracy); if (isCompromised) { android.Compromised = true; switch (android.AutoPilot) { case AutoPilot.Level1: android.Team.Score -= 10; break; case AutoPilot.Level2: android.Team.Score -= 100; break; case AutoPilot.Level3: android.Team.Score -= 1000; break; } } await dbContext.SaveChangesAsync(); Console.WriteLine($"[ HTF2017 - datarequest for '{android.Team.Name}' processed and fulfilled. ]"); } else { Console.WriteLine($"[ HTF2017 - PANIC - No team found for android '{dataRequest.AndroidId}'! ]"); } } } }
private static async Task HandlePendingSensoryData() { using (HtfDbContext dbContext = new HtfDbContext()) { Console.WriteLine("[ HTF2017 - Getting pending sensory data... ]"); List <SensoryData> data = await dbContext.SensoryData .Where(x => !x.Sent).OrderBy(x => x.TimeStamp).ToListAsync(); Console.WriteLine( $"[ HTF2017 - {(data.Count > 0 ? $"{data.Count}" : "no")} pending sensory data found. ]"); foreach (SensoryData d in data) { Team team = await dbContext.Androids.Where(x => x.Id == d.AndroidId) .Select(x => x.Team).SingleOrDefaultAsync(); if (team != null) { Console.WriteLine($"[ HTF2017 - Processing data for '{team.Name}'. ]"); Boolean received = false; try { RestClient client = new RestClient(team.FeedbackEndpoint); RestRequest request = new RestRequest(Method.POST); FeedbackRequestDto feedback = new FeedbackRequestDto { AndroidId = d.AndroidId, Longitude = d.Longitude, Lattitude = d.Lattitude, Crowd = d.Crowd, Mood = d.Mood, Relationship = d.Relationship, TimeStamp = d.TimeStamp, AutonomousRequest = d.AutonomousRequested }; request.AddJsonBody(feedback); FeedbackResponseDto response = await client.PostTaskAsync <FeedbackResponseDto>(request); if (response != null && response.TeamId == team.Id) { if (d.AutonomousRequested) { team.Score += 10; } else { team.Score += 20; } received = true; } else { team.Score--; } } catch { team.Score--; } d.Sent = true; d.Received = received; await dbContext.SaveChangesAsync(); Console.WriteLine($"[ HTF2017 - data for '{team.Name}' {(received ? "successfully sent" : "failed to send")}. ]"); } else { Console.WriteLine($"[ HTF2017 - PANIC - No team found for android '{d.AndroidId}'! ]"); } await Task.Delay(100); } } }
public async Task AddDefaultLocations() { _dbContext.Locations.Add(new Location { Name = "Central Europe", Lattitude = 49.9194008, Longitude = 6.0430397 }); _dbContext.Locations.Add(new Location { Name = "Northern Europe", Lattitude = 61.9912145, Longitude = 12.6579873 }); _dbContext.Locations.Add(new Location { Name = "Southern Europe", Lattitude = 41.3949627, Longitude = 2.0086849 }); _dbContext.Locations.Add(new Location { Name = "Eastern Europe", Lattitude = 48.2444995, Longitude = 30.0446145 }); _dbContext.Locations.Add(new Location { Name = "United States of America", Lattitude = 39.8646026, Longitude = -101.5089545 }); _dbContext.Locations.Add(new Location { Name = "Canada", Lattitude = 59.5760083, Longitude = -112.109443 }); _dbContext.Locations.Add(new Location { Name = "Central America", Lattitude = 14.7545596, Longitude = -87.475112 }); _dbContext.Locations.Add(new Location { Name = "South America", Lattitude = -8.7831897, Longitude = -55.4936657 }); _dbContext.Locations.Add(new Location { Name = "Russia", Lattitude = 61.2921444, Longitude = 89.5103138 }); _dbContext.Locations.Add(new Location { Name = "New Zealand", Lattitude = -43.3392148, Longitude = 172.461096 }); _dbContext.Locations.Add(new Location { Name = "Australia", Lattitude = -24.8535582, Longitude = 132.7571009 }); _dbContext.Locations.Add(new Location { Name = "China", Lattitude = 34.7868527, Longitude = 102.0331196 }); _dbContext.Locations.Add(new Location { Name = "Central Africa", Lattitude = 6.706757, Longitude = 20.0973021 }); _dbContext.Locations.Add(new Location { Name = "South Africa", Lattitude = -33.9030916, Longitude = 18.4071074 }); _dbContext.Locations.Add(new Location { Name = "United Arab Emirates", Lattitude = 23.9818299, Longitude = 53.9452593 }); _dbContext.Locations.Add(new Location { Name = "Greenland", Lattitude = 66.7866238, Longitude = -46.9413866 }); _dbContext.Locations.Add(new Location { Name = "India", Lattitude = 21.9761621, Longitude = 77.2527611 }); _dbContext.Locations.Add(new Location { Name = "Japan", Lattitude = 35.7861952, Longitude = 138.8864704 }); _dbContext.Locations.Add(new Location { Name = "Indonesia", Lattitude = -1.304056, Longitude = 113.9298059 }); await _dbContext.SaveChangesAsync(); }