Exemplo n.º 1
0
        /// <summary>
        /// Checks if a ScheduledSetting is active, and returns a newly mirrored Output object with modified Value. If not found, returns same input back.
        /// There's an interesting issue here when a range passes midnight (2300-0300 for instance) that might need to be handled better, idea being schedules should be able to run all day long in real time without reboots.
        /// NOTE: this will change sending output if there is an active schedule.
        /// If value of input is 0, ignore changing and return input unchanged.
        /// </summary>
        /// <param name="currentOutput">Output / port of device.</param>
        /// <param name="startingdeviceIndex">Specifies start index of device ID (1st UIO=27).</param>
        /// <param name="currentdeviceIndex">Specifies active index of device ID (for UIO this is zero-based, making the 1st UIO #27).</param>
        public IOutput getnewrecalculatedOutput(IOutput currentOutput, int startingdeviceIndex, int currentdeviceIndex)
        {
            if (currentOutput.Value != 0)
            {
                //create a new dummy output with no event mirroring input arg to avoid triggering a recursive OnOutputValueChanged (modifying Output directly would retrigger this method)
                Output newOutput = new Output();
                newOutput.Value  = currentOutput.Value;
                newOutput.Name   = currentOutput.Name;
                newOutput.Number = currentOutput.Number;

                //Log.Write("ScheduledSettings.getnewrecalculatedOutput..name=" + newOutput.Name + ", number=" + newOutput.Number + ", currentdeviceIndex=" + currentdeviceIndex);
                ScheduledSettingDevice ActiveScheduleDevice = GetActiveSchedule(newOutput, true, startingdeviceIndex, currentdeviceIndex);

                if (ActiveScheduleDevice != null)
                {
                    return(newOutput);
                }
                else
                {
                    return(currentOutput);
                }
            }
            else
            {
                return(currentOutput);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks if a ScheduledSetting is active; enabled, within time region, among list of affected outputs, and of correct device ID.
        /// When the time calculations here are done, make sure and update the ScheduledSetting directly so we won't need to do this every event.
        /// There's an interesting issue here when a range passes midnight (2300-0300 for instance) that might need to be handled better, idea being schedules should be able to run all day long in real time without reboots.
        /// </summary>
        /// <param name="currentOutput">Output / port of device.</param>
        /// <param name="recalculateoutputValue">If true, recalculates output value directly.</param>
        /// <param name="startingdeviceIndex">Specifies start index of device ID (1st UIO=27).</param>
        /// <param name="currentdeviceIndex">Specifies active index of device ID (for UIO this is zero-based, making the 1st UIO #27).</param>
        public ScheduledSettingDevice GetActiveSchedule(IOutput currentOutput, bool recalculateoutputValue, int startingdeviceIndex, int currentdeviceIndex)
        {
            ScheduledSettingDevice foundactiveDevice   = null;
            ScheduledSetting       foundactiveSchedule = null;


            //possible to add result into cache for faster processing next time?


            foreach (ScheduledSetting scheduledSetting in this)
            {
                //first check if enabled
                if (scheduledSetting.Enabled == true)
                {
                    //Log.Write("ScheduledSettings.GetActiveSchedule, enabled: "+scheduledSetting.Name+", checking time range...");

                    //next check if within time range using military time (1730 etc)
                    string clockStart = scheduledSetting.ClockStart;
                    string clockEnd   = scheduledSetting.ClockEnd;

                    //convert military string time to actual time of current day
                    //it's important this is done in real time, not at dof boot as it probably wouldn't become active again if a pincab was online more than a day...which is why we need to recalculate using real time
                    DateTime datetimeStart           = DateTime.ParseExact(clockStart, "HHmm", CultureInfo.InvariantCulture);
                    DateTime datetimeEnd             = DateTime.ParseExact(clockEnd, "HHmm", CultureInfo.InvariantCulture);
                    long     currenttimeMilliseconds = DateTime.Now.Ticks;

                    //check if we're passing midnight, and if we are add a day to clockend...now, this gets pretty interesting, a real spinning clock helped programming this thing :)
                    //will this work again on next midnight?

                    //scenario; time is 1200, range is 2200-1400... since we still haven't passed end clock, do not advance one day ahead for end time since we're assuming clockstart is in the past (last day).. instead set start time one day back and assume we've passed midnight
                    //scenario; time is 1200, range is 1000-1400... since we're within time range and within the same day, don't advance either start or end
                    if (int.Parse(clockEnd) < int.Parse(clockStart) && currenttimeMilliseconds < datetimeEnd.Ticks)
                    {
                        datetimeStart = datetimeStart.AddDays(-1);
                    }
                    else if (int.Parse(clockEnd) < int.Parse(clockStart))
                    {
                        datetimeEnd = datetimeEnd.AddDays(1);
                    }

                    //Log.Write("ScheduledSettings.GetActiveSchedule, current time="+DateTime.Now+", start-end: " + datetimeStart.ToString()+" - "+datetimeEnd.ToString());
                    //Log.Write("ScheduledSettings.GetActiveSchedule, currenttimeMilliseconds="+ currenttimeMilliseconds);
                    //Log.Write("ScheduledSettings.GetActiveSchedule, start-end: " + datetimeStart.Ticks+" - "+datetimeEnd.Ticks);

                    //check if within time region, and if we are check if output port and device id is in list
                    if (currenttimeMilliseconds >= datetimeStart.Ticks && currenttimeMilliseconds <= datetimeEnd.Ticks)
                    {
                        //Log.Write("ScheduledSettings.GetActiveSchedule, within time range: "+scheduledSetting.ClockStart+"-"+scheduledSetting.ClockEnd+", checking device ids and output list...");

                        foreach (ScheduledSettingDevice scheduledsettingDevice in scheduledSetting.ScheduledSettingDeviceList)
                        {
                            if ((currentdeviceIndex + startingdeviceIndex) == scheduledsettingDevice.ConfigPostfixID && scheduledsettingDevice.OutputList.Contains(currentOutput.Number))
                            {
                                //Log.Write("ScheduledSettings.GetActiveSchedule... " + scheduledSetting.Name + " is active [" + clockStart + "-" + clockEnd + "] at channel #" + currentOutput.Number + " on device " + scheduledsettingDevice.Name);
                                foundactiveDevice   = scheduledsettingDevice;
                                foundactiveSchedule = scheduledSetting;
                                break;
                            }
                        }
                    }
                }
            }

            //recalculate output value based on strength?
            if (foundactiveDevice != null && recalculateoutputValue == true)
            {
                double strengthFactor = foundactiveDevice.OutputPercent / 100f;
                byte   newValue       = Convert.ToByte(currentOutput.Value * strengthFactor);

                if (CacheList.Contains(foundactiveDevice) == false)
                {
                    CacheList.Add(foundactiveDevice);

                    if (currentOutput.Value != 0)
                    {
                        Log.Write("ScheduledSettings.GetActiveSchedule: found active schedule: " + foundactiveSchedule.Name + " [" + foundactiveSchedule.ClockStart + "-" + foundactiveSchedule.ClockEnd + "] at channel #" + currentOutput.Number + " on device config " + foundactiveDevice.Name + ", applying strength multiplier: " + strengthFactor + ", old value=" + currentOutput.Value + ", new value=" + newValue);
                    }
                }

                if (foundactiveDevice.OutputPercent == 0 && currentOutput.Value != 0)
                {
                    currentOutput.Value = 0;
                }
                else if (foundactiveDevice.OutputPercent != 100)
                {
                    currentOutput.Value = newValue;
                }
            }

            return(foundactiveDevice);
        }