/// <summary>
        /// Execute the actions required for proper greenhouse functioning, based on the input data from API calls
        /// </summary>
        /// <param name="sensorData"></param>
        /// <param name="manualControls"></param>
        /// <param name="automationData"></param>
        public void ExecuteActions(SensorPacket[] sensorData, ManualControlPacket manualControls, AutomationPacket automationData)
        {
            // Make sure the Arduino stays awake
            ArduinoControlSender.Instance.CheckArduinoStatus();

            // Process limit changes
            LimitsAnalyzer limitAnalyzer = new LimitsAnalyzer();

            limitAnalyzer.ChangeGreenhouseLimits(automationData);

            // Make sure the Arduino stays awake
            ArduinoControlSender.Instance.CheckArduinoStatus();

            // Process manual data
            ManualPacketAnalyzer manualAnalyzer = new ManualPacketAnalyzer();

            manualAnalyzer.SetManualValues(manualControls);

            // Make sure the Arduino stays awake
            ArduinoControlSender.Instance.CheckArduinoStatus();
            // Process sensor data
            AnalyzeData(sensorData);
        }
        /// <summary>
        /// Change the greenhouse limits based on the API automation data
        /// </summary>
        /// <param name="limits"></param>
        public void ChangeGreenhouseLimits(AutomationPacket limits)
        {
            if (StateMachineContainer.Instance.Temperature.HighLimit != limits.TempHigh)
            {
                StateMachineContainer.Instance.Temperature.HighLimit = limits.TempHigh;
            }
            if (StateMachineContainer.Instance.Temperature.LowLimit != limits.TempLow)
            {
                StateMachineContainer.Instance.Temperature.LowLimit = limits.TempLow;
            }
            if (StateMachineContainer.Instance.Shading.HighLimit != limits.ShadeLim)
            {
                StateMachineContainer.Instance.Shading.HighLimit = limits.ShadeLim;
            }
            if (limits.LightSchedules != null)
            {
                foreach (ZoneSchedule schedule in limits.LightSchedules)
                {
                    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;
                    }
                }
            }

            if (limits.WaterSchedules != null)
            {
                foreach (ZoneSchedule schedule in limits.WaterSchedules)
                {
                    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}");
            }
        }