Beispiel #1
0
 /// <summary>
 /// Write this sensor out to a configuration file
 /// </summary>
 /// <param name="r"></param>
 /// <returns></returns>
 public void Serialize(string filename)
 {
     try {
         var settings = new JsonSerializerSettings();
         settings.TypeNameHandling = TypeNameHandling.Objects;
         settings.Formatting       = Newtonsoft.Json.Formatting.Indented;
         var s = JsonConvert.SerializeObject(SensorProject.Current, settings);
         File.WriteAllText(filename, s);
     } catch (Exception ex) {
         SensorProject.LogException("Error saving sensor project", ex);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Collect data for this sensor (with parameter - not used!)
        /// </summary>
        public async Task OuterCollect()
        {
            DateTime               collectStartTime  = DateTime.MinValue;
            DateTime               collectFinishTime = DateTime.MinValue;
            bool                   success           = false;
            TimeSpan               ts   = new TimeSpan();
            SensorData             sd   = null;
            SensorCollectEventArgs args = new SensorCollectEventArgs();

            // Collect data and clock how long it took
            try {
                collectStartTime = DateTime.UtcNow;
                args.Raw         = await Collect();

                collectFinishTime = DateTime.UtcNow;
                ts = collectFinishTime - collectStartTime;

                // Record what was collected
                LastCollectTime = collectFinishTime;
                sd      = AddValue(args.Raw.Value, collectStartTime, (int)ts.TotalMilliseconds);
                success = true;

                // If something blew up, keep track of it
            } catch (Exception ex) {
                args.Exception = new SensorException()
                {
                    Cleared       = false,
                    Description   = ex.Message,
                    ExceptionTime = DateTime.UtcNow,
                    StackTrace    = ex.StackTrace
                };
                LastException = ex.ToString();
                InError       = true;
                if (PauseOnError)
                {
                    Enabled = false;
                    SensorProject.LogException("Sensor error & pause: (#" + this.Identity + ") " + this.Name, ex);
                }
                else
                {
                    SensorProject.LogException("Sensor error: (#" + this.Identity + ") " + this.Name, ex);
                }

                // Release the inflight status so that this sensor can collect again
            } finally {
                // Move forward to next collection time period - skip any number of intermediate time periods
                if (NextCollectTime < DateTime.UtcNow)
                {
                    NextCollectTime = DateTime.UtcNow.AddSeconds((int)Frequency);
                }

                // Allow this to be recollected again
                InFlight = false;
            }

            // Now, all elements that can safely be moved after the inflight flag is turned off
            if (success)
            {
                args.Data = new Common.SensorData()
                {
                    CollectionTimeMs = (int)ts.TotalMilliseconds,
                    Time             = collectFinishTime,
                    Value            = args.Raw.Value
                };

                // Is anyone listening?
                if (this.SensorCollect != null)
                {
                    SensorCollect(this, args);
                }
            }

            // Notify everyone of what happened
            if (Children != null)
            {
                foreach (ICondition c in Children)
                {
                    c.TestCondition(args);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Read a sensor back from a node from an XML file
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        public static SensorProject Deserialize(string filename)
        {
            SensorProject sp = null;

            // Read in the text
            try {
                var settings = new JsonSerializerSettings();
                settings.TypeNameHandling = TypeNameHandling.Objects;
                settings.Formatting       = Newtonsoft.Json.Formatting.Indented;
                string s = File.ReadAllText(filename);
                sp = JsonConvert.DeserializeObject <SensorProject>(s, settings);

                // Failed to load
            } catch (Exception ex) {
                SensorProject.LogException("Error loading sensor file", ex);
                sp = new SensorProject();
            }

            // Now make all the sensors read their data
            Current = sp;
            List <int> sensor_id_list = new List <int>();

            foreach (IDevice dc in sp.Children)
            {
                dc.Parent = SensorProject.Current;

                // Go through all sensors for this device
                foreach (ISensor bs in dc.Children)
                {
                    // Make sure each sensor is uniquely identified!  If any have duplicate IDs, uniqueify them
                    if (sensor_id_list.Contains(bs.Identity))
                    {
                        bs.Identity = sp.NextSensorNum++;
                    }
                    sensor_id_list.Add(bs.Identity);
                    bs.Parent = (IDevice)dc;

                    // Read in each sensor's data, and write it back out to disk
                    // (this ensures that all files have the same fields in the same order - permits appending via AppendText later
                    bs.DataRead();

                    // Loop through all conditions / actions
                    foreach (ICondition c in bs.Children)
                    {
                        c.Parent = bs;
                        foreach (IAction a in c.Children)
                        {
                            a.Parent = c;
                        }
                    }
                }
            }

            // Ensure that the log folder exists
            if (!Directory.Exists("logs"))
            {
                Directory.CreateDirectory("Logs");
            }

            // Save this as the current project
            return(sp);
        }
Beispiel #4
0
        /// <summary>
        /// This is the background thread for collecting data
        /// </summary>
        public async void CollectionThread()
        {
            // Okay, let's enter the loop
            while (_keep_running)
            {
                int      collect_count     = 0;
                DateTime next_collect_time = DateTime.MaxValue;

                // Be safe about this - we don't want this thread to blow up!  It's the only one we've got
                try {
                    // Loop through sensors, and spawn a work item for them
                    for (int i = 0; i < Children.Count; i++)
                    {
                        IDevice dc = Children[i] as IDevice;
                        for (int j = 0; j < dc.Children.Count; j++)
                        {
                            // Allow us to kick out
                            if (!_keep_running)
                            {
                                return;
                            }

                            // Okay, let's work on this sensor
                            ISensor s = dc.Children[j] as ISensor;
                            if ((s.Enabled) && (!s.InFlight) && (s.Frequency != Interval.Never))
                            {
                                // Spawn a work item in the thread pool to do this collection task
                                if (s.NextCollectTime <= DateTime.UtcNow)
                                {
                                    s.InFlight = true;
                                    Task.Run(() => s.OuterCollect());
                                    collect_count++;

                                    // If it's not time yet, use this to factor when next to wake up
                                }
                                else
                                {
                                    if (s.NextCollectTime < next_collect_time)
                                    {
                                        next_collect_time = s.NextCollectTime;
                                    }
                                }
                            }
                        }
                    }

                    // Failsafe
                } catch (Exception ex) {
                    SensorProject.LogException("Collect", ex);
                }

                // Sleep until next collection time, but allow ourselves to kick out
                if (!_keep_running)
                {
                    return;
                }
                TimeSpan time_to_sleep    = next_collect_time - DateTime.UtcNow;
                int      clean_sleep_time = Math.Max(1, Math.Min((int)time_to_sleep.TotalMilliseconds, 1000));
                await Task.Delay(clean_sleep_time);
            }
        }