/// <summary>
        /// Takes in a BlockingCollection and removes data. Sends data to be assessed elsewhere
        /// </summary>
        /// <param name="source">Blocking collection used to hold data for producer consumer pattern</param>
        public void ReceiveGreenhouseData(BlockingCollection <byte[]> source)
        {
            // Create a container for the TLH and moisture packets so we can deserialize them easily
            TLHPacketContainer      tlhContainer      = new TLHPacketContainer();
            MoisturePacketContainer moistureContainer = new MoisturePacketContainer();

            // Take the bytes out of the queue and turn them back into a string
            source.TryTake(out _data);
            string json = Encoding.ASCII.GetString(_data);

            // Take the string to a JObject and deserialize according to the appropriate Type value
            JObject received = JObject.Parse(json);

            Console.WriteLine(received.ToString());
            switch (received["Type"].Value <int>())
            {
            case 0:
                tlhContainer    = JsonConvert.DeserializeObject <TLHPacketContainer>(json);
                _tlhInformation = tlhContainer.Packets;
                break;

            case 1:
                moistureContainer    = JsonConvert.DeserializeObject <MoisturePacketContainer>(json);
                _moistureInformation = moistureContainer.Packets;
                break;

            case 2:
                _limits = JsonConvert.DeserializeObject <LimitPacket>(json);
                break;

            case 3:
                _manual = JsonConvert.DeserializeObject <ManualPacket>(json);
                break;
            }

            // If we have all the TLH information, moisture information, limit and manual information we need...
            if (_tlhInformation != null && _moistureInformation != null && _limits != null && _manual != null)
            {
                Console.WriteLine("Sending to analyzers");

                // Put everything into temporary variables and clear their values afterwards
                TLHPacket[] tlhToSend = new TLHPacket[_tlhInformation.Count];
                _tlhInformation.CopyTo(tlhToSend);
                _tlhInformation.Clear();

                MoisturePacket[] moistureToSend = new MoisturePacket[_moistureInformation.Count];
                _moistureInformation.CopyTo(moistureToSend);
                _moistureInformation.Clear();

                ManualPacket tempManual = _manual;
                _manual = null;
                LimitPacket tempLimits = _limits;
                _limits = null;

                // Send the temporary variables off to be analyzed
                DataAnalyzer data = new DataAnalyzer();
                data.ExecuteActions(tlhToSend, moistureToSend, tempManual, tempLimits);
            }
        }
        /// <summary>
        /// Execute the actions required for proper greenhouse functioning, based on the input data
        /// </summary>
        /// <param name="temperature">Array of temperature, lighting, and humidity information packets</param>
        /// <param name="moisture">Array of moisture information packets</param>
        /// <param name="manual">Packet containing any manual commands we may have received</param>
        /// <param name="limits">Packet containng the greenhouse automation limits</param>
        public void ExecuteActions(TLHPacket[] temperature, MoisturePacket[] moisture, ManualPacket manual, LimitPacket limits)
        {
            ArduinoControlSender.Instance.CheckArduinoStatus();
            // Process limit changes
            LimitsAnalyzer limitAnalyzer = new LimitsAnalyzer();

            limitAnalyzer.ChangeGreenhouseLimits(limits);
            // Process manual controls
            ArduinoControlSender.Instance.CheckArduinoStatus();
            ManualPacketAnalyzer manualAnalyzer = new ManualPacketAnalyzer();

            manualAnalyzer.SetManualValues(manual);
            // Process sensor data
            ArduinoControlSender.Instance.CheckArduinoStatus();
            AnalyzeData(temperature, moisture);
        }
        /// <summary>
        /// Changes the greenhouse limits based on the limit packet data
        /// </summary>
        /// <param name="limits"></param>
        public void ChangeGreenhouseLimits(LimitPacket limits)
        {
            if (StateMachineContainer.Instance.Temperature.HighLimit != limits.TempHi)
            {
                StateMachineContainer.Instance.Temperature.HighLimit = limits.TempHi;
            }
            if (StateMachineContainer.Instance.Temperature.LowLimit != limits.TempLo)
            {
                StateMachineContainer.Instance.Temperature.LowLimit = limits.TempLo;
            }
            if (StateMachineContainer.Instance.Shading.HighLimit != limits.ShadeLim)
            {
                StateMachineContainer.Instance.Shading.HighLimit = limits.ShadeLim;
            }
            foreach (ZoneSchedule schedule in limits.Light)
            {
                switch (schedule.zone)
                {
                case 1:
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].Begin             = schedule.start;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].End               = schedule.end;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].OverrideThreshold = schedule.threshold;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].ScheduleType      = schedule.type;
                    break;

                case 2:
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].Begin             = schedule.start;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].End               = schedule.end;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].OverrideThreshold = schedule.threshold;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].ScheduleType      = schedule.type;
                    break;

                case 3:
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].Begin             = schedule.start;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].End               = schedule.end;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].OverrideThreshold = schedule.threshold;
                    StateMachineContainer.Instance.LightStateMachines[schedule.zone - 1].ScheduleType      = schedule.type;
                    break;
                }
            }
            foreach (ZoneSchedule schedule in limits.Water)
            {
                StateMachineContainer.Instance.WateringStateMachines[schedule.zone - 1].Begin             = schedule.start;
                StateMachineContainer.Instance.WateringStateMachines[schedule.zone - 1].End               = schedule.end;
                StateMachineContainer.Instance.WateringStateMachines[schedule.zone - 1].OverrideThreshold = schedule.threshold;
                StateMachineContainer.Instance.WateringStateMachines[schedule.zone - 1].ScheduleType      = schedule.type;
            }

            Console.WriteLine($"Temperature High Limit: {StateMachineContainer.Instance.Temperature.HighLimit}");
            Console.WriteLine($"Temperature Low Limit: {StateMachineContainer.Instance.Temperature.LowLimit}");
            Console.WriteLine($"Shading Limit: {StateMachineContainer.Instance.Shading.HighLimit}");

            for (int i = 0; i < StateMachineContainer.Instance.LightStateMachines.Count; i++)
            {
                Console.WriteLine($"LZone {StateMachineContainer.Instance.LightStateMachines[i].Zone}"
                                  + $"Start: {StateMachineContainer.Instance.LightStateMachines[i].Begin}"
                                  + $"\nLZone {StateMachineContainer.Instance.LightStateMachines[i].Zone}"
                                  + $"End: {StateMachineContainer.Instance.LightStateMachines[i].End}"
                                  );
            }

            for (int i = 0; i < StateMachineContainer.Instance.WateringStateMachines.Count; i++)
            {
                Console.WriteLine($"WZone {StateMachineContainer.Instance.WateringStateMachines[i].Zone}"
                                  + $"Start: {StateMachineContainer.Instance.WateringStateMachines[i].Begin}"
                                  + $"\nWZone {StateMachineContainer.Instance.WateringStateMachines[i].Zone}"
                                  + $"End: {StateMachineContainer.Instance.WateringStateMachines[i].End}");
            }
        }
        /// <summary>
        /// Takes in a BlockingCollection and removes data. Sends data to be assessed elsewhere
        /// </summary>
        /// <param name="source">Blocking collection used to hold data for producer consumer pattern</param>
        public void ReceiveGreenhouseData(BlockingCollection <byte[]> source)
        {
            // TODO: Fix this up so that it doesn't mess with things already happening within state machines, etc.
            if (source.Count != 0)
            {
                try
                {
                    source.TryTake(out _data);
                    var data = JObject.Parse(Encoding.ASCII.GetString(_data));

                    Console.WriteLine(data.ToString());


                    if (data["Type"].Value <int>() == 0)
                    {
                        _currentTime = data["TimeOfSend"].Value <DateTime>();
                        var deserializedData = JsonConvert.DeserializeObject <TLHPacket>(Encoding.ASCII.GetString(_data));

                        // Check for repeat zones, and if we have any, throw out the old zone data
                        if (_tlhInformation.Where(p => p.ID == deserializedData.ID) != null)
                        {
                            _tlhInformation.RemoveAll(p => p.ID == deserializedData.ID);
                        }

                        _tlhInformation.Add(deserializedData);
                    }
                    // if it's a moisture packet
                    else if (data["Type"].Value <int>() == 1)
                    {
                        var deserializedData = JsonConvert.DeserializeObject <MoisturePacket>(Encoding.ASCII.GetString(_data));

                        // Check for repeat zones, and if we have any, throw out the old zone data
                        if (_moistureInformation.Where(p => p.ID == deserializedData.ID) != null)
                        {
                            _moistureInformation.RemoveAll(p => p.ID == deserializedData.ID);
                        }

                        _moistureInformation.Add(deserializedData);
                    }
                    else if (data["Type"].Value <int>() == 2)
                    {
                        var deserializedData = JsonConvert.DeserializeObject <LimitPacket>(Encoding.ASCII.GetString(_data));

                        _limits = deserializedData;
                    }
                    else if (data["Type"].Value <int>() == 3)
                    {
                        var deserializedData = JsonConvert.DeserializeObject <ManualPacket>(Encoding.ASCII.GetString(_data));

                        _manual = deserializedData;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }

                if (_tlhInformation.Count == 5 && _moistureInformation.Count == 6 && _limits != null && _manual != null)
                {
                    TLHPacket[] tlhToSend = new TLHPacket[_tlhInformation.Count];
                    _tlhInformation.CopyTo(tlhToSend);
                    _tlhInformation.Clear();

                    MoisturePacket[] moistureToSend = new MoisturePacket[_moistureInformation.Count];
                    _moistureInformation.CopyTo(moistureToSend);
                    _moistureInformation.Clear();

                    ManualPacket tempManual = _manual;
                    _manual = null;
                    LimitPacket tempLimits = _limits;
                    _limits = null;

                    DataAnalyzer data = new DataAnalyzer();
                    Task.Run(() => data.ExecuteActions(tlhToSend, moistureToSend, tempManual, tempLimits));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Changes the  greenhouse limits based on the limit packet data
        /// </summary>
        /// <param name="limits"></param>
        public void ChangeGreenhouseLimits(LimitPacket limits)
        {
            if (StateMachineContainer.Instance.Temperature.HighLimit != limits.TempHi)
            {
                StateMachineContainer.Instance.Temperature.HighLimit = limits.TempHi;
            }
            if (StateMachineContainer.Instance.Temperature.LowLimit != limits.TempLo)
            {
                StateMachineContainer.Instance.Temperature.LowLimit = limits.TempLo;
            }
            if (StateMachineContainer.Instance.Shading.HighLimit != limits.ShadeLim)
            {
                StateMachineContainer.Instance.Shading.HighLimit = limits.ShadeLim;
            }
            foreach (KeyValuePair <int, DateTime> kvp in limits.LightStarts)
            {
                switch (kvp.Key)
                {
                case 1:
                    StateMachineContainer.Instance.LightStateMachines[0].Begin = kvp.Value;
                    break;

                case 3:
                    StateMachineContainer.Instance.LightStateMachines[1].Begin = kvp.Value;
                    break;

                case 5:
                    StateMachineContainer.Instance.LightStateMachines[1].Begin = kvp.Value;
                    break;

                default:
                    break;
                }
            }
            foreach (KeyValuePair <int, DateTime> kvp in limits.LightEnds)
            {
                switch (kvp.Key)
                {
                case 1:
                    StateMachineContainer.Instance.LightStateMachines[0].End = kvp.Value;
                    break;

                case 3:
                    StateMachineContainer.Instance.LightStateMachines[1].End = kvp.Value;
                    break;

                case 5:
                    StateMachineContainer.Instance.LightStateMachines[2].End = kvp.Value;
                    break;

                default:
                    break;
                }
            }
            foreach (KeyValuePair <int, DateTime> kvp in limits.WaterStarts)
            {
                switch (kvp.Key)
                {
                case 1:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                case 2:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                case 3:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                case 4:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                case 5:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                case 6:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].Begin = kvp.Value;
                    break;

                default:
                    break;
                }
            }
            foreach (KeyValuePair <int, DateTime> kvp in limits.WaterEnds)
            {
                switch (kvp.Key)
                {
                case 1:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                case 2:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                case 3:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                case 4:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                case 5:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                case 6:
                    StateMachineContainer.Instance.WateringStateMachines[kvp.Key - 1].End = kvp.Value;
                    break;

                default:
                    break;
                }
            }

            Console.WriteLine($"Temperature High Limit: {StateMachineContainer.Instance.Temperature.HighLimit}");
            Console.WriteLine($"Temperature Low Limit: {StateMachineContainer.Instance.Temperature.LowLimit}");
            Console.WriteLine($"Shading Limit: {StateMachineContainer.Instance.Shading.HighLimit}");

            for (int i = 0; i < StateMachineContainer.Instance.LightStateMachines.Count; i++)
            {
                Console.WriteLine($"LZone {StateMachineContainer.Instance.LightStateMachines[i].Zone}"
                                  + $"Start: {StateMachineContainer.Instance.LightStateMachines[i].Begin}"
                                  + $"\nLZone {StateMachineContainer.Instance.LightStateMachines[i].Zone}"
                                  + $"End: {StateMachineContainer.Instance.LightStateMachines[i].End}"
                                  );
            }

            for (int i = 0; i < StateMachineContainer.Instance.WateringStateMachines.Count; i++)
            {
                Console.WriteLine($"WZone {StateMachineContainer.Instance.WateringStateMachines[i].Zone}"
                                  + $"Start: {StateMachineContainer.Instance.WateringStateMachines[i].Begin}"
                                  + $"\nWZone {StateMachineContainer.Instance.WateringStateMachines[i].Zone}"
                                  + $"End: {StateMachineContainer.Instance.WateringStateMachines[i].End}");
            }
        }