/// <summary> /// Removes the listener for the specified sensor /// </summary> public void RemoveListener(Sensor sensor, Action <Sensor> listener) { if (Logger.DUMP) { Logger.dump("SensorRegistry", "RemoveListener " + sensor.ID + " " + listener.ToString()); } lock (sync_listener) { if (!activeSensors.ContainsKey(sensor)) { return; // TODO: handle errors? } SensorListener sl = activeSensors[sensor]; var removed = sl.listeners.RemoveAll((g) => { return(g == listener); }); if (removed > 0) { sensor.NotifyRemoveListener(listener); } if (sl.listeners.Count == 0) { activeSensors.Remove(sensor); } activeSensors_array = null; } }
protected override void Activate() { Logger.dump("DerivedSensor", "Activate: " + this.ID); LoadBaseSensors(); if (this.a != null) { base.registry.AddListener(this.a, this.OnSensorChange, Interval); } if (this.b != null) { base.registry.AddListener(this.b, this.OnSensorChange, Interval); } }
void ListenerHandler() { while (triggerQueue != null) { if (triggerQueue.Count == 0) { Thread.Sleep(10); } else { SensorListener sl = null; var sensor = triggerQueue.Dequeue(); if (sensor != null) { activeSensors.TryGetValue(sensor, out sl); } if (sl != null) { sl.nextReading = DateTimeMs.Now + sl.period; if (Logger.DUMP) { Logger.dump("SensorRegistry", "ListenerHandler " + sensor.ID + " " + sl.nextReading); } foreach (Action <Sensor> l in sl.listeners.ToArray()) { try{ if (Logger.DUMP) { Logger.dump("SensorRegistry", "Listener: " + l); } l(sensor); }catch (Exception e) { Logger.error("SensorRegistry", "Listener fail on: " + sensor.ID, e); } } foreach (Action <Sensor> l in PassiveListeners.ToArray()) { try{ l(sensor); }catch (Exception e) { Logger.error("SensorRegistry", "Passive listener fail on: " + sensor.ID, e); } } } } } }
public void TriggerListeners(Sensor sensor) { if (sensor == null) { throw new ArgumentNullException(); } SensorListener sl = null; activeSensors.TryGetValue(sensor, out sl); if (Logger.DUMP && sl != null) { Logger.dump("SensorRegistry", "TriggerListeners " + sensor.ID + "=" + sensor.Value + " listeners:" + sl.listeners.Count + " nr=" + (sl.nextReading - DateTimeMs.Now)); } if (sl != null && triggerQueue != null && (sl.nextReading == 0 || sl.nextReading <= DateTimeMs.Now)) { triggerQueue.Enqueue(sensor); } }
protected virtual void SensorChanged(Sensor sensor) { SensorTrackData set; if (!Settings.TryGetValue(sensor.ID, out set)) { set = new SensorTrackData(); set.id = sensor.ID; Settings.Add(set.id, set); } if (set.LastTimeStamp == sensor.TimeStamp) { return; } if (Logger.DUMP) { Logger.dump("SensorTrack", "SensorChanged " + sensor.ID); } lock (set) { if (set.length > 0 && set.stopat == 0) { set.stopat = sensor.TimeStamp + set.length; } if (set.stopat != 0 && sensor.TimeStamp >= set.stopat) { set.startat = sensor.TimeStamp + set.gap; set.stopat = 0; Registry.RemoveListener(sensor, this.SensorChanged); //TODO: raise timer } StoreSensor(sensor); } }
/// <summary> /// Detaches the specifed listener for all sensors /// </summary> /// <param name="listener"> /// A <see cref="Action<Sensor>"/> /// </param> public void RemoveListener(Action <Sensor> listener) { if (Logger.DUMP) { Logger.dump("SensorRegistry", "RemoveListener " + listener.ToString()); } lock (sync_listener) { foreach (var sl in activeSensors.Values.ToArray()) { var removed = sl.listeners.RemoveAll((g) => { return(g == listener); }); if (removed > 0) { sl.sensor.NotifyRemoveListener(listener); } if (sl.listeners.Count == 0) { activeSensors.Remove(sl.sensor); } } activeSensors_array = null; } }
/// <summary> /// Adds listener for the specified sensor /// </summary> /// <remarks> /// Use period of milliseconds to /// update the reading. Default is 0 - means update as fast as possible /// </remarks> public void AddListener(Sensor sensor, Action <Sensor> listener, int period) { if (Logger.DUMP) { Logger.dump("SensorRegistry", "AddListener " + sensor.ID + " " + listener.ToString() + " " + period); } lock (sync_listener) { if (sensor == null) { throw new NullReferenceException("Null sensor"); } SensorListener sl = null; try{ sl = activeSensors[sensor]; }catch (KeyNotFoundException) { sl = new SensorListener(); sl.sensor = sensor; sl.period = period; activeSensors.Add(sensor, sl); } if (sl.period > period) { sl.period = period; sl.nextReading = 0; } if (!sl.listeners.Contains(listener)) { sl.listeners.Add(listener); #if DEBUG sl.bt += Environment.StackTrace; #endif sensor.NotifyAddListener(listener); } activeSensors_array = null; } }
void HandleState() { if (State == ST_ERROR) { Thread.Sleep(SleepOnError); return; } // Means no sensor reading was performed - we have // to wait and search for another sensor if (State == ST_SENSOR) { Thread.Sleep(50); SetState(ST_SENSOR); return; } if (stream.HasData()) { byte[] data = stream.Read(); if (data != null) { if (position + data.Length < buffer.Length) { Array.Copy(data, 0, buffer, position, data.Length); position = position + data.Length; } else { Logger.error("OBD2Engine", "BUFFER OVERFLOW! " + position + data.Length); position = 0; } if (Logger.DUMP) { Logger.dump("OBD2Engine", "BUFFER: " + Encoding.ASCII.GetString(buffer, 0, position)); } if (ReadDelay > 0) { if (Logger.TRACE) { Logger.trace("OBD2Engine", "Sleeping " + ReadDelay + " ms"); } Thread.Sleep(ReadDelay); } if (data.Length > 0) { lastReceiveTS = DateTimeMs.Now; } } data = null; } // nothing to read - wait if (position == 0) { Thread.Sleep(50); return; } for (int isearch = 0; isearch < position; isearch++) { // end of reply found if (buffer[isearch] == '>') { byte[] msg = new byte[isearch]; Array.Copy(buffer, 0, msg, 0, isearch); isearch++; Array.Copy(buffer, isearch, buffer, 0, position - isearch); position = position - isearch; // handle our extracted message HandleReply(msg); break; } } }
void SetState(string state2) { State = state2; StateDetails = state2; lastReceiveTS = DateTimeMs.Now; if (Logger.TRACE) { Logger.trace("OBD2Engine", " -> " + State); } switch (State) { case ST_SENSOR: fireStateNotify(STATE_READ); break; case ST_SENSOR_ACK: fireStateNotify(STATE_READ_DONE); break; case ST_ERROR: case ST_ERROR_SOFT: fireStateNotify(STATE_ERROR); break; default: fireStateNotify(STATE_INIT); break; } switch (State) { case ST_INIT_HW: Error = null; try{ stream.Close(); Logger.info("OBD2Engine", "Open " + url); Thread.Sleep(100); stream.Open(url); }catch (Exception e) { Error = e.Message; Logger.error("OBD2Engine", "Init Error", e); SetState(ST_ERROR); break; } PurgeStream(); SetState(ST_INIT); break; case ST_INIT: extraInitCommands.Clear(); extraInitIndex = 0; if (CriticalError) { CriticalError = false; // trigger protocol autosearch TODO: conflicts with some settings, f.e. ATFI setup //extraInitCommands.Add("ATSP 0"); } if (initData != null) { initData.Split(new char[] { ';' }).ToList().ForEach((s) => { var cmd = s.Trim(); if (cmd.Length > 0) { extraInitCommands.Add(cmd); } }); } SensorInitIndex = 0; SetState(ST_ATZ); break; case ST_ATZ: SendCommand("ATZ"); break; case ST_ATE0: SendCommand("ATE0"); break; case ST_ATL0: SendCommand("ATL0"); break; case ST_EXTRAINIT: if (extraInitIndex >= extraInitCommands.Count()) { SetState(ST_SENSOR_INIT); } else { SendCommand(extraInitCommands[extraInitIndex]); StateDetails = State + " " + this.extraInitCommands[this.extraInitIndex]; extraInitIndex++; } break; case ST_SENSOR_INIT: SendCommand("01" + SensorInitIndex.ToString("X2")); break; case ST_QUERY_PROTOCOL: SendCommand("ATDPN"); break; case ST_SENSOR: var sls = Registry.ActiveSensors; if (sls.Length == 0) { if (Logger.TRACE) { Logger.trace("OBD2Engine", " no active sensors "); } break; } currentSensorIndex++; if (currentSensorIndex >= sls.Length) { currentSensorIndex = 0; } int scanSensorIndex = currentSensorIndex; while (true) { currentSensorListener = sls[currentSensorIndex]; // recreate reading timers if layout was changed! if (nextReadings == null || nextReadings.Length != sls.Length) { nextReadings = new long[sls.Length]; } long nextReading = nextReadings[currentSensorIndex]; if (nextReading == 0 || nextReading <= DateTimeMs.Now) { if (currentSensorListener.sensor is OBD2Sensor) { if (Logger.TRACE) { Logger.trace("OBD2Engine", " ----> " + currentSensorListener.sensor.ID); } var osensor = (OBD2Sensor)currentSensorListener.sensor; var cmd = osensor.RawCommand; if (cmd != null) { LinesSent = SendCommand(cmd); SetState(ST_SENSOR_ACK); break; } else { // move to next sensor } } } else { if (Logger.DUMP) { Logger.dump("OBD2Engine", " Skipped " + currentSensorListener.sensor.ID + " with " + (nextReading - DateTimeMs.Now)); } } currentSensorIndex++; if (currentSensorIndex >= sls.Length) { currentSensorIndex = 0; } if (currentSensorIndex == scanSensorIndex) { break; } } break; } }