protected Sensor(string name, SensorAttribute attributes, WiseSafeToOperate instance) { wisesafetooperate = instance; WiseName = name; _attributes = attributes; _timer = new System.Threading.Timer(new TimerCallback(onTimer)); if (HasAttribute(SensorAttribute.AlwaysEnabled)) { Enabled = true; } _state = SensorState.None; Restart(5000); activityMonitor.Event(new Event.SafetyEvent( sensor: WiseName, details: "Created", before: sensorState, after: Event.SafetyEvent.SensorState.Init)); sensorState = Event.SafetyEvent.SensorState.Init; }
// // The timer is enabled ONLY on non-Immediate sensors // private void onTimer(object StateObject) { if (!Enabled) { return; } DateTime now = DateTime.Now; Reading currentReading = getReading(); if (currentReading == null) { return; } if (_readings == null) { _readings = new FixedSizedQueue <Reading>(_nreadings); } Reading[] arr = _readings.ToArray(); List <string> values = new List <string>(); int nbad = 0, nstale = 0, nreadings = 0; foreach (Reading r in arr) // before current reading { values.Add(r.ToString()); nreadings++; if (!r.safe) { nbad++; } if (r.stale) { nstale++; } } SensorState savedState = _state; bool wassafe = StateIsSet(SensorState.Safe); bool wasready = StateIsSet(SensorState.EnoughReadings); _readings.Enqueue(currentReading); arr = _readings.ToArray(); values = new List <string>(); nbad = 0; nstale = 0; nreadings = 0; foreach (Reading r in arr) // including current reading { values.Add(r.ToString()); nreadings++; if (!r.safe) { nbad++; } if (r.stale) { nstale++; } } debugger.WriteLine(Debugger.DebugLevel.DebugSafety, "onTimer: Sensor ({0}) readings: [{1}]", WiseName, String.Join(",", values)); _nreadings = nreadings; _nbad = nbad; _nstale = nstale; lock (_lock) { UnsetState(SensorState.Safe); if (HasAttribute(SensorAttribute.CanBeStale) && (_nstale > 0)) { ExtendUnsafety(string.Format("{0} stale reading{1}", _nstale, _nstale > 1 ? "s" : "")); SetState(SensorState.Stale); return; // Remain unsafe - at least one stale reading } else { UnsetState(SensorState.Stale); } if (_readings.ToArray().Count() != _repeats) { UnsetState(SensorState.EnoughReadings); return; // Remain unsafe - not enough readings } else { if (!StateIsSet(SensorState.EnoughReadings)) { activityMonitor.Event(new Event.SafetyEvent( sensor: WiseName, details: "Became ready", before: sensorState, after: Event.SafetyEvent.SensorState.Ready)); sensorState = Event.SafetyEvent.SensorState.Ready; } SetState(SensorState.EnoughReadings); } if (_nbad == _repeats) { ExtendUnsafety("All readings are unsafe"); if (wasready && wassafe) { activityMonitor.Event(new Event.SafetyEvent( sensor: WiseName, details: "Became unsafe", before: sensorState, after: Event.SafetyEvent.SensorState.NotSafe)); } sensorState = Event.SafetyEvent.SensorState.NotSafe; return; // Remain unsafe - all readings are unsafe } bool prolong = true; if (StateIsSet(SensorState.Stabilizing)) { if (currentReading.stale || !currentReading.safe) { ExtendUnsafety("Unsafe reading while stabilizing"); return; } if (now.CompareTo(_endOfStabilization) <= 0) { return; } else { UnsetState(SensorState.Stabilizing); prolong = false; // don't prolong if just ended stabilization } } // If we got here the sensor is currently safe if (wasready && StateIsSet(SensorState.EnoughReadings) && !wassafe && prolong) { ExtendUnsafety("Readings just turned safe"); return; // Remain unsafe - just begun stabilizing } SetState(SensorState.Safe); if (wasready && !wassafe) { activityMonitor.Event(new Event.SafetyEvent( sensor: WiseName, details: "Became safe", before: sensorState, after: Event.SafetyEvent.SensorState.Safe)); } sensorState = Event.SafetyEvent.SensorState.Safe; } }