public DateTime GetMostRecentRecordTimestamp(string signalID) { MOE.Common.Models.Controller_Event_Log row = (from r in _db.Controller_Event_Log where r.SignalID == signalID orderby r.Timestamp descending select r).Take(1).FirstOrDefault(); if (row != null) { return(row.Timestamp); } else { return(new DateTime()); } }
static public DateTime GetMostRecentRecordTimestamp(string signalID) { Models.SPM db = new Models.SPM(); DateTime twoDaysAgo = DateTime.Now.AddDays(-2); MOE.Common.Models.Controller_Event_Log row = (from r in db.Controller_Event_Log where r.SignalID == signalID && r.Timestamp > twoDaysAgo orderby r.Timestamp descending select r).Take(1).FirstOrDefault(); if (row != null) { return(row.Timestamp); } else { return(twoDaysAgo); } }
protected void AddDataToChart(Chart chart) { List <ControllerEventLogs> Tables = new List <ControllerEventLogs>(); List <DateTime> SplitFails = new List <DateTime>(); int totalFails = 0; Models.Repositories.ISignalsRepository signalRepository = Models.Repositories.SignalsRepositoryFactory.Create(); //var signal = signalRepository.GetSignalBySignalID(phase.SignalID); var ApproachDetectors = Phase.Approach.GetDetectorsForMetricType(12); //get occupancy events for each lane for the approach. if (ApproachDetectors.Count() > 0) { foreach (Models.Detector row in ApproachDetectors) { MOE.Common.Business.ControllerEventLogs TEMPdetectortable = new ControllerEventLogs(Phase.SignalID, Options.StartDate, Options.EndDate, row.DetChannel, new List <int>() { 81, 82 }); if (TEMPdetectortable.Events.Count > 0) { Tables.Add(TEMPdetectortable); } } Dictionary <string, string> statistics = new Dictionary <string, string>(); if (Tables.Count > 0) { //for (int CurCycleIndex = 0; CurCycleIndex < phase.Cycles.Count -1 ; CurCycleIndex++) //int tempCycleCounter = 0; //Parallel.ForEach(phase.Cycles, c => foreach (MOE.Common.Business.CustomReport.Cycle c in Phase.Cycles) { //tempCycleCounter++; //SplitFailDetectorActivationCollection activations = new SplitFailDetectorActivationCollection(); //for each lane //Parallel.ForEach(Tables, table => foreach (ControllerEventLogs table in Tables) { int channel = table.Events[0].EventParam; List <MOE.Common.Models.Controller_Event_Log> DetectorHitsForCycle = new List <MOE.Common.Models.Controller_Event_Log>(); //Parallel.ForEach(table.Events, e => foreach (MOE.Common.Models.Controller_Event_Log e in table.Events) { if (e.Timestamp >= c.CycleStart && e.Timestamp <= c.CycleEnd) { DetectorHitsForCycle.Add(e); } } //); if (DetectorHitsForCycle.Count > 0) { var eventsInOrder = DetectorHitsForCycle.OrderBy(r => r.Timestamp); if (eventsInOrder.Count() > 1) { for (int i = 0; i < eventsInOrder.Count() - 1; i++) { MOE.Common.Models.Controller_Event_Log current = eventsInOrder.ElementAt(i); MOE.Common.Models.Controller_Event_Log next = eventsInOrder.ElementAt(i + 1); if (current.Timestamp.Ticks == next.Timestamp.Ticks) { continue; } //If the first event is 'Off', then set 'On' to cyclestart if (i == 0 && current.EventCode == 81) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = c.CycleStart; da.DetectorOff = current.Timestamp; c.Activations.AddActivation(da); } //This is the prefered sequence; an 'On' followed by an 'off' if (current.EventCode == 82 && next.EventCode == 81) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = current.Timestamp; da.DetectorOff = next.Timestamp; c.Activations.AddActivation(da); continue; } //if we are at the penultimate event, and the last event is 'on', set 'off' as CycleEnd. if (i + 2 == eventsInOrder.Count() && next.EventCode == 82) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = next.Timestamp; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); continue; } } } else { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); MOE.Common.Models.Controller_Event_Log current = eventsInOrder.First(); switch (current.EventCode) { //if the only event is off case 81: da.DetectorOn = c.CycleStart; da.DetectorOff = current.Timestamp; c.Activations.AddActivation(da); break; //if the only event is on case 82: da.DetectorOn = current.Timestamp; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); break; } } } //if there are no hits in the cycle, we need to determine if the a previous detector activaition lasts the entire cycle else if (DetectorHitsForCycle.Count <= 0) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); DateTime earlierTime = c.CycleStart.AddMinutes(-30); List <int> li = new List <int> { 81, 82 }; ControllerEventLogs cs = new ControllerEventLogs(Phase.SignalID, earlierTime, c.CycleStart, channel, li); //if the last detecotr eventCodes was ON, and there is no matching off event, assume the detector was on for the whole cycle if (cs.Events.Count > 0 && cs.Events.LastOrDefault().EventCode == 82) { da.DetectorOn = c.CycleStart; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); } //} } } //); //end of Lane loop //merge the detectors for the different lanes for (int i = 0; i < c.Activations.Activations.Count - 1;) { SplitFailDetectorActivation current = c.Activations.Activations.ElementAt(i).Value; SplitFailDetectorActivation next = c.Activations.Activations.ElementAt(i + 1).Value; //if the next activaiton is between the previos one, remove the nextone and start again. if (next.DetectorOn >= current.DetectorOn && next.DetectorOff <= current.DetectorOff) { c.Activations.Activations.RemoveAt(i + 1); continue; } //if the next activaiton starts during the current, but ends later, atler current end time, and remove next, and start over. else if (next.DetectorOn >= current.DetectorOn && next.DetectorOn < current.DetectorOff && next.DetectorOff > current.DetectorOff) { current.DetectorOff = next.DetectorOff; c.Activations.Activations.RemoveAt(i + 1); continue; } else { i++; } } //if (c.Activations.Activations.Count > 0 && c.CycleStart > startDate && c.CycleStart < endDate) if (c.CycleStart > Options.StartDate && c.CycleStart < Options.EndDate) { double gor = c.Activations.GreenOccupancy(c) * 100; double ror = c.Activations.StartOfRedOccupancy(c, Options.FirstSecondsOfRed) * 100; if (c.TerminationEvent == MOE.Common.Business.CustomReport.Cycle.TerminationCause.GapOut) { chart.Series["GOR - GapOut"].Points.AddXY(c.CycleStart, gor); chart.Series["ROR - GapOut"].Points.AddXY(c.CycleStart, ror); } else { chart.Series["GOR - ForceOff"].Points.AddXY(c.CycleStart, gor); chart.Series["ROR - ForceOff"].Points.AddXY(c.CycleStart, ror); } if ((gor > 79 && ror > 79)) { if (Options.ShowFailLines) { chart.Series["SplitFail"].Points.AddXY(c.CycleStart, 100); } SplitFails.Add(c.CycleStart); totalFails++; } } } //); statistics.Add("Total Split Failures ", totalFails.ToString()); //end of Cycle loop //Average Loop DateTime counterTime = Options.StartDate; do { double binTotalGOR = 0; double binTotalROR = 0; var CycleBin = from cur in Phase.Cycles where cur.CycleStart >= counterTime && cur.CycleStart <= counterTime.AddMinutes(15) orderby cur.CycleStart select cur; var failsInBin = from s in SplitFails where s >= counterTime && s <= counterTime.AddMinutes(15) select s; double binFails = failsInBin.Count(); //Parallel.ForEach(CycleBin, c => foreach (MOE.Common.Business.CustomReport.Cycle c in CycleBin) { binTotalGOR += c.Activations.GreenOccupancy(c) * 100; binTotalROR += c.Activations.StartOfRedOccupancy(c, Options.FirstSecondsOfRed) * 100; } //); if (Options.ShowPercentFailLines) { if (binFails > 0 && CycleBin.Count() > 0) { double binFailPercent = (binFails / Convert.ToDouble(CycleBin.Count())); chart.Series["Percent Fails"].Points.AddXY(counterTime, Convert.ToInt32(binFailPercent * 100)); } else { chart.Series["Percent Fails"].Points.AddXY(counterTime, 0); } } if (Options.ShowAvgLines) { if (CycleBin.Count() > 0) { double avggor = binTotalGOR / CycleBin.Count(); double avgror = binTotalROR / CycleBin.Count(); chart.Series["Avg. GOR"].Points.AddXY(counterTime, avggor); chart.Series["Avg. ROR"].Points.AddXY(counterTime, avgror); } if (CycleBin.Count() == 0) { chart.Series["Avg. GOR"].Points.AddXY(counterTime, 0); chart.Series["Avg. ROR"].Points.AddXY(counterTime, 0); } } counterTime = counterTime.AddMinutes(15); } while (counterTime < Options.EndDate.AddMinutes(15)); //End Average Loop } SetChartTitle(statistics); AddPlanStrips(chart, Phase, Options.StartDate, Options.EndDate, SplitFails); } }
public static void SetPedTimesForCycle(List <Models.Controller_Event_Log> pedeventsForCycle, PhaseCycleBase cycle) { if (pedeventsForCycle.Count > 0) { var orderedevents = pedeventsForCycle.OrderBy(r => r.Timestamp); if (orderedevents.Count() > 1) { for (int i = 0; i < orderedevents.Count() - 1; i++) { MOE.Common.Models.Controller_Event_Log current = orderedevents.ElementAt(i); MOE.Common.Models.Controller_Event_Log next = orderedevents.ElementAt(i + 1); if (current.Timestamp.Ticks == next.Timestamp.Ticks) { //i++; continue; } //If the first event is 'Off', then set duration to 0 if (i == 0 && current.EventCode == 23) { cycle.PedStart = cycle.CycleStart; //cycle.SetPedEnd(current.Timestamp); cycle.PedEnd = cycle.CycleEnd; } //This is the prefered sequence; an 'On' followed by an 'off' if (current.EventCode == 21 && next.EventCode == 23) { if (cycle.PedStart == DateTime.MinValue) { cycle.PedStart = current.Timestamp; } else if ((cycle.PedStart > current.Timestamp)) { cycle.PedStart = current.Timestamp; } if (cycle.PedEnd == DateTime.MinValue) { cycle.PedEnd = next.Timestamp; } else if ((cycle.PedEnd < next.Timestamp)) { cycle.PedEnd = next.Timestamp; } continue; } //if we are at the penultimate event, and the last event is 'on' then set duration to 0. if (i + 2 == orderedevents.Count() && next.EventCode == 21) { cycle.PedStart = cycle.CycleStart; //cycle.SetPedEnd(cycle.YellowEvent); cycle.PedEnd = cycle.CycleEnd; ; continue; } } } else { MOE.Common.Models.Controller_Event_Log current = orderedevents.First(); switch (current.EventCode) { //if the only event is off case 23: cycle.PedStart = cycle.CycleStart; cycle.PedEnd = cycle.CycleStart; //cycle.SetPedEnd(current.Timestamp); break; //if the only event is on case 21: cycle.PedStart = current.Timestamp; cycle.PedEnd = current.Timestamp; //cycle.SetPedEnd(cycle.YellowEvent); break; } } } }
public void SetPedTimesForCycle(List <Models.Controller_Event_Log> PedEventsForCycle, AnalysisPhaseCycle Cycle) { if (PedEventsForCycle.Count > 0) { var eventsInOrder = PedEventsForCycle.OrderBy(r => r.Timestamp); if (eventsInOrder.Count() > 1) { for (int i = 0; i < eventsInOrder.Count() - 1; i++) { MOE.Common.Models.Controller_Event_Log current = eventsInOrder.ElementAt(i); MOE.Common.Models.Controller_Event_Log next = eventsInOrder.ElementAt(i + 1); if (current.Timestamp.Ticks == next.Timestamp.Ticks) { //i++; continue; } //If the first event is 'Off', then set duration to 0 if (i == 0 && current.EventCode == 23) { Cycle.SetPedStart(Cycle.StartTime); //Cycle.SetPedEnd(current.Timestamp); Cycle.SetPedEnd(Cycle.StartTime); } //This is the prefered sequence; an 'On' followed by an 'off' if (current.EventCode == 21 && next.EventCode == 23) { if (Cycle.PedStartTime == DateTime.MinValue) { Cycle.SetPedStart(current.Timestamp); } else if ((Cycle.PedStartTime > current.Timestamp)) { Cycle.SetPedStart(current.Timestamp); } if (Cycle.PedEndTime == DateTime.MinValue) { Cycle.SetPedEnd(next.Timestamp); } else if ((Cycle.PedEndTime < next.Timestamp)) { Cycle.SetPedEnd(next.Timestamp); } continue; } //if we are at the penultimate event, and the last event is 'on' then set duration to 0. if (i + 2 == eventsInOrder.Count() && next.EventCode == 21) { Cycle.SetPedStart(Cycle.StartTime); //Cycle.SetPedEnd(Cycle.YellowEvent); Cycle.SetPedEnd(Cycle.StartTime); continue; } } } else { MOE.Common.Models.Controller_Event_Log current = eventsInOrder.First(); switch (current.EventCode) { //if the only event is off case 23: Cycle.SetPedStart(Cycle.StartTime); Cycle.SetPedEnd(Cycle.StartTime); //Cycle.SetPedEnd(current.Timestamp); break; //if the only event is on case 21: Cycle.SetPedStart(current.Timestamp); Cycle.SetPedEnd(current.Timestamp); //Cycle.SetPedEnd(Cycle.YellowEvent); break; } } } }
private void GetGreenYellowRedCycle(DateTime startTime, DateTime endTime, List <Models.Controller_Event_Log> cycleEvents, List <Models.Controller_Event_Log> detectorEvents, List <Models.Controller_Event_Log> preemptEvents) { Cycle pcd = null; //use a counter to help determine when we are on the last row int counter = 0; foreach (MOE.Common.Models.Controller_Event_Log row in cycleEvents) { //use a counter to help determine when we are on the last row counter++; if (row.Timestamp >= startTime && row.Timestamp <= endTime) { //If this is the first PCD Group we need to handle a special case //where the pcd starts at the start of the requested period to //make sure we include all data if (CycleCollection.Count == 0 && pcd == null) { //Make the first group start on at the exact start of the requested period pcd = new Cycle(startTime); //Add a green event if the first event is yellow if (GetEventType(row.EventCode) == Cycle.EventType.ChangeToYellow) { pcd.NextEvent(Cycle.EventType.ChangeToGreen, startTime.AddMilliseconds(1)); } //Add a green and yellow event if first event is red else if (GetEventType(row.EventCode) == Cycle.EventType.ChangeToRed) { pcd.NextEvent(Cycle.EventType.ChangeToGreen, startTime.AddMilliseconds(1)); pcd.NextEvent(Cycle.EventType.ChangeToYellow, startTime.AddMilliseconds(2)); } } //Check to see if the event is a change to red //The 64 event is for overlaps. if (row.EventCode == 10 || row.EventCode == 64) { //If it is red and the pcd group is empy create a new one if (pcd == null) { pcd = new Cycle(row.Timestamp); } //If the group is not empty than it is the end of the group and the start //of the next group else { pcd.NextEvent(GetEventType(row.EventCode), row.Timestamp); //if the nextevent response is complete add it and start the next group if (pcd.Status == Cycle.NextEventResponse.GroupComplete) { //pcd.setdetectorcollection(detectortable); CycleCollection.Add(pcd); pcd = new Cycle(row.Timestamp); } } } //If the event is not red and the group is not empty //add the event and set the next event else if (pcd != null) { pcd.NextEvent(GetEventType(row.EventCode), row.Timestamp); if (pcd.Status == Cycle.NextEventResponse.GroupComplete) { CycleCollection.Add(pcd); pcd = new Cycle(row.Timestamp); } } if (pcd != null && pcd.Status == Cycle.NextEventResponse.GroupMissingData) { pcd = null; } //If this is the last PCD Group we need to handle a special case //where the pcd starts at the start of the requested period to //make sure we include all data else if (counter == cycleEvents.Count() && pcd != null) { //if the last event is red create a new group to consume the remaining //time in the period if (GetEventType(row.EventCode) == Cycle.EventType.ChangeToRed) { pcd.NextEvent(Cycle.EventType.ChangeToGreen, endTime.AddMilliseconds(-2)); pcd.NextEvent(Cycle.EventType.ChangeToYellow, endTime.AddMilliseconds(-1)); pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } else if (GetEventType(row.EventCode) == Cycle.EventType.ChangeToGreen) { pcd.NextEvent(Cycle.EventType.ChangeToYellow, endTime.AddMilliseconds(-1)); pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } else if (GetEventType(row.EventCode) == Cycle.EventType.ChangeToYellow) { pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } if (pcd.Status != Cycle.NextEventResponse.GroupMissingData) { CycleCollection.Add(pcd); } } } } //if there are no records at all for the selected time, then the line //and counts don't show. This next bit fixes that. if (CycleCollection.Count == 0 && (startTime != endTime)) { //then we need to make a dummy PDC group //the pcd assumes it starts on red. pcd = new Cycle(startTime); //and find out what phase state the controller was in by looking for the next phase event //after the end of the plan. MOE.Common.Models.Controller_Event_Log eventBeforePattern = null; try { eventBeforePattern = MOE.Common.Business.ControllerEventLogs.GetEventBeforeEvent(this.SignalID, this.PhaseNumber, startTime); } finally { } if (eventBeforePattern != null) { if (GetEventType(eventBeforePattern.EventCode) == Cycle.EventType.ChangeToRed) { //let it dwell in red (we don't have to add anything). //then add a green phase, a yellow phase and a red phase at the end to complete the cycle pcd.NextEvent(Cycle.EventType.ChangeToGreen, endTime.AddMilliseconds(-2)); pcd.NextEvent(Cycle.EventType.ChangeToYellow, endTime.AddMilliseconds(-1)); pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } else if (GetEventType(eventBeforePattern.EventCode) == Cycle.EventType.ChangeToYellow) { //we were in yellow, though this will probably never happen //We have to add a green to our dummy phase. pcd.NextEvent(Cycle.EventType.ChangeToGreen, startTime.AddMilliseconds(1)); //then make it dwell in yellow pcd.NextEvent(Cycle.EventType.ChangeToYellow, startTime.AddMilliseconds(2)); //then add a red phase at the end to complete the cycle pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } else if (GetEventType(eventBeforePattern.EventCode) == Cycle.EventType.ChangeToGreen) { // make it dwell in green pcd.NextEvent(Cycle.EventType.ChangeToGreen, startTime.AddMilliseconds(1)); //then add a yellow phase and a red phase at the end to complete the cycle pcd.NextEvent(Cycle.EventType.ChangeToYellow, endTime.AddMilliseconds(-1)); pcd.NextEvent(Cycle.EventType.ChangeToRed, endTime); } } if (pcd.Status == Cycle.NextEventResponse.GroupComplete) { CycleCollection.Add(pcd); } } AddDetectorData(detectorEvents); AddPreemptData(preemptEvents); }