Ejemplo n.º 1
0
        // clears the existing list of program items and replaces them with the items from xml file; changes loop settings, local/remote and period settings according to the xml file
        public void ReplaceItems(BindingList <ProgramItem> programItems, out bool loopIsEnabled, out int loopCount, out bool isRemote, out double periodSeconds, out TimeUnits periodTimeUnits)
        {
            loopIsEnabled   = false;
            loopCount       = 1;
            isRemote        = false;
            periodSeconds   = 1;
            periodTimeUnits = TimeUnits.s;
            programItems.Clear(); // clear program items list

            document.Load(this.path);
            XmlElement main;

            main = document.DocumentElement;

            // loop
            foreach (XmlNode node in main.ChildNodes)
            {
                if (node.Name == "loop")
                {
                    loopIsEnabled = true;
                    if (node.Attributes.GetNamedItem("count").Value == "infinite")
                    {
                        loopCount = 0;
                    }
                    else
                    {
                        loopCount = Int32.Parse(node.Attributes.GetNamedItem("count").Value);
                    }
                    break;
                }
            }

            // remote/local
            XmlNode remote;

            remote   = main.SelectSingleNode("voltageSenseMode");
            isRemote = Boolean.Parse(remote.Attributes.GetNamedItem("isRemote").Value);

            // period settings
            XmlNode loggingPeriod;

            loggingPeriod   = main.SelectSingleNode("logging");
            periodTimeUnits = (TimeUnits)Enum.Parse(typeof(TimeUnits), loggingPeriod.Attributes.GetNamedItem("timeUnit").Value);
            timeConverter   = new Converters.TimeConverter(); // convert representation in time-unit to seconds
            periodSeconds   = (double)(timeConverter.ConvertBack(loggingPeriod.Attributes.GetNamedItem("period").Value, typeof(string), periodTimeUnits, System.Globalization.CultureInfo.CurrentCulture));
            // elements
            AddItems(programItems);
        }
Ejemplo n.º 2
0
        internal LogSettings(Load program)
        {
            InitializeComponent();
            this.program  = program;
            timeConverter = new Converters.TimeConverter();

            // fill with current values
            textBoxPeriod.Text = (string)(timeConverter.Convert(program.LoggingPeriod, typeof(string), program.LoggingTimeUnit, System.Globalization.CultureInfo.CurrentCulture));
            comboBoxUnit.Items.Clear();
            for (byte i = 0; i < (Enum.GetValues(typeof(TimeUnits))).Length; i++)
            {
                comboBoxUnit.Items.Add((TimeUnits)i);
                if ((byte)(program.LoggingTimeUnit) == i)
                {
                    comboBoxUnit.SelectedIndex = i;
                }
            }
        }
Ejemplo n.º 3
0
        // creates constant mode program item
        private void constant(Modes mode, double?value, string durationString, TimeUnits timeUnit)
        {
            this.programMode    = ProgramModes.Constant;
            this.mode           = mode;
            this.durationString = durationString;
            this.timeUnit       = timeUnit;
            this.value          = value;
            this.skipEnabled    = false;

            // compute duration in seconds
            Converters.TimeConverter timeConverter = new Converters.TimeConverter();
            this.duration = (double)(timeConverter.ConvertBack(durationString, typeof(double), timeUnit, System.Globalization.CultureInfo.CurrentCulture));

            // string representation for GUI
            switch (mode)
            {
            case Modes.Current:
            {
                if (value != null)
                {
                    this.name = "Constant current " + ((double)value).ToString(NUMBER_FORMAT) + " A, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant current (use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Power_CC:
            {
                if (value != null)
                {
                    this.name = "Constant power (CC) " + ((double)value).ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant power (CC, use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Power_CV:
            {
                if (value != null)
                {
                    this.name = "Constant power (CV) " + ((double)value).ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant power (CV, use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Resistance_CC:
            {
                if (value != null)
                {
                    this.name = "Constant resistance (CC) " + ((double)value).ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant resistance (CC, use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Resistance_CV:
            {
                if (value != null)
                {
                    this.name = "Constant resistance (CV) " + ((double)value).ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant resistance (CV, use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Voltage:
            {
                if (value != null)
                {
                    this.name = "Constant voltage " + ((double)value).ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant voltage (use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.VoltageSoftware:
            {
                if (value != null)
                {
                    this.name = "Constant SW controlled voltage " + ((double)value).ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Constant SW controlled voltage (use previous), " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.MPPT:
            {
                if (value != null)
                {
                    //this.name = "Maximum power point tracker from " + ((double)value).ToString(NUMBER_FORMAT) + " A, " + durationString + " " + timeUnit.ToString();
                    this.name = "Maximum power point tracker from " + ((double)value).ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    //this.name = "Maximum power point tracker (use previous current), " + durationString + " " + timeUnit.ToString();
                    this.name = "Maximum power point tracker (use previous voltage), " + durationString + " " + timeUnit.ToString();
                }

                break;
            }

            case Modes.SimpleAmmeter:
            {
                name = "Simple ammeter, " + durationString + " " + timeUnit.ToString();
                break;
            }
            }
        }
Ejemplo n.º 4
0
        // creates ramp mode program item
        private void ramp(Modes mode, double?startingValue, double finalValue, string durationString, TimeUnits timeUnit)
        {
            this.programMode    = ProgramModes.Ramp;
            this.mode           = mode;
            this.durationString = durationString;
            this.timeUnit       = timeUnit;
            this.startingValue  = startingValue;
            this.finalValue     = finalValue;

            // compute duration in seconds
            Converters.TimeConverter timeConverter = new Converters.TimeConverter();
            this.duration = (double)(timeConverter.ConvertBack(durationString, typeof(double), timeUnit, System.Globalization.CultureInfo.CurrentCulture));

            // string representation for GUI
            switch (mode)
            {
            case Modes.Current:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp current " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " A, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp current (use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " A, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Power_CC:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp power (CC) " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp power (CC, use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Power_CV:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp power (CV) " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp power (CV, use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " W, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Resistance_CC:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp resistance (CC) " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp resistance (CC, use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Resistance_CV:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp resistance (CV) " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp resistance (CV, use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " Ω, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.Voltage:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp voltage " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp voltage (use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }

            case Modes.VoltageSoftware:
            {
                if (startingValue != null)
                {
                    this.name = "Ramp SW controlled voltage " + ((double)startingValue).ToString(NUMBER_FORMAT) + " –> " + finalValue.ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                else
                {
                    this.name = "Ramp SW controlled voltage (use previous) –> " + finalValue.ToString(NUMBER_FORMAT) + " V, " + durationString + " " + timeUnit.ToString();
                }
                break;
            }
            }
        }
Ejemplo n.º 5
0
        public void LoadSettings(out bool loopIsEnabled, out int loopCount, out bool isRemote, out double periodSeconds, out TimeUnits periodTimeUnits, out LEDBrightnesses LEDBrightness, out byte LEDRule, out FanRules FanRule, out MeasurementFilters MeasurementFilter, out bool CurrentAutoranging, out bool VoltageAutoranging)
        {
            loopIsEnabled   = false;
            loopCount       = 1;
            isRemote        = false;
            periodSeconds   = 1;
            periodTimeUnits = TimeUnits.s;

            document.Load(this.path);
            XmlElement main;

            main = document.DocumentElement;

            // loop
            foreach (XmlNode node in main.ChildNodes)
            {
                if (node.Name == "loop")
                {
                    loopIsEnabled = true;
                    if (node.Attributes.GetNamedItem("count").Value == "infinite")
                    {
                        loopCount = 0;
                    }
                    else
                    {
                        loopCount = Int32.Parse(node.Attributes.GetNamedItem("count").Value);
                    }
                    break;
                }
            }

            // remote/local
            XmlNode remote;

            remote   = main.SelectSingleNode("voltageSenseMode");
            isRemote = Boolean.Parse(remote.Attributes.GetNamedItem("isRemote").Value);

            // LED settings
            XmlNode LED;

            LED = main.SelectSingleNode("LED");
            // brightness
            LEDBrightnesses lb;

            if (Enum.TryParse(LED.Attributes.GetNamedItem("brightness").Value, out lb))
            {
                LEDBrightness = lb;
            }
            else
            {
                LEDBrightness = Load.DefaultLEDBrightness;
            }
            // rules
            byte   ledRule;
            bool   result;
            string hex = LED.Attributes.GetNamedItem("rules").Value;

            if (hex.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
            {
                result = byte.TryParse(hex.Substring(2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out ledRule);
            }
            else
            {
                result = byte.TryParse(hex, out ledRule);
            }
            if (result)
            {
                LEDRule = ledRule;
            }
            else
            {
                LEDRule = Load.DefaultLEDRule;
            }

            // Fan
            XmlNode Fan;

            Fan = main.SelectSingleNode("fan");
            // rule
            FanRules fr;

            if (Enum.TryParse(Fan.Attributes.GetNamedItem("rules").Value, out fr))
            {
                FanRule = fr;
            }
            else
            {
                FanRule = Load.DefaultFanRule;
            }

            // Measurement
            XmlNode Measurement;

            Measurement = main.SelectSingleNode("measurement");
            // filter
            MeasurementFilters ms;

            if (Enum.TryParse(Measurement.Attributes.GetNamedItem("filter").Value, out ms))
            {
                MeasurementFilter = ms;
            }
            else
            {
                MeasurementFilter = Load.DefaultMeasurementFilter;
            }

            // Autoranging
            XmlNode Autoranging;

            Autoranging = main.SelectSingleNode("autoranging");
            // current
            if (bool.TryParse(Autoranging.Attributes.GetNamedItem("current").Value, out CurrentAutoranging) == false)
            {
                CurrentAutoranging = Load.DefaultAutorangingCurrent;
            }
            // voltage
            if (bool.TryParse(Autoranging.Attributes.GetNamedItem("voltage").Value, out VoltageAutoranging) == false)
            {
                VoltageAutoranging = Load.DefaultAutorangingVoltage;
            }

            // period settings
            XmlNode loggingPeriod;

            loggingPeriod   = main.SelectSingleNode("logging");
            periodTimeUnits = (TimeUnits)Enum.Parse(typeof(TimeUnits), loggingPeriod.Attributes.GetNamedItem("timeUnit").Value);
            timeConverter   = new Converters.TimeConverter(); // convert representation in time-unit to seconds
            periodSeconds   = (double)(timeConverter.ConvertBack(loggingPeriod.Attributes.GetNamedItem("period").Value, typeof(string), periodTimeUnits, System.Globalization.CultureInfo.CurrentCulture));
        }
Ejemplo n.º 6
0
        // creates Xml file with program items, loop info, local/remote info and period settings
        public void SaveItems(BindingList <ProgramItem> programItems, bool loopIsEnabled, int loopCount, bool isRemote,
                              double logPeriod, TimeUnits logTimeUnit, LEDBrightnesses LEDBrightness, byte LEDRule, FanRules FanRule, MeasurementFilters MeasurementFilter, bool AutorangingCurrent, bool AutorangingVoltage)
        {
            XmlNode declaration = document.CreateXmlDeclaration("1.0", "UTF-8", null);

            document.AppendChild(declaration);
            XmlNode comment = document.CreateComment("MightyWatt R3 experiment settings");

            document.AppendChild(comment);
            XmlElement main = document.CreateElement("settings");

            document.AppendChild(main);

            if (loopIsEnabled == true)
            {
                // loop settings
                XmlNode loop = document.CreateElement("loop");

                // duration
                XmlAttribute count = document.CreateAttribute("count");
                if (loopCount < 0)
                {
                    count.Value = "infinite";
                }
                else
                {
                    count.Value = loopCount.ToString();
                }
                loop.Attributes.Append(count);
                main.AppendChild(loop);
            }

            // local/remote settings
            XmlNode remote = document.CreateElement("voltageSenseMode");

            main.AppendChild(remote);
            // is remote
            XmlAttribute isrem = document.CreateAttribute("isRemote");

            isrem.Value = isRemote.ToString();
            remote.Attributes.Append(isrem);

            // LED settings
            XmlNode LED = document.CreateElement("LED");

            main.AppendChild(LED);
            // brightness
            XmlAttribute brightness = document.CreateAttribute("brightness");

            brightness.Value = Enum.GetName(typeof(LEDBrightnesses), LEDBrightness);
            LED.Attributes.Append(brightness);
            // rules
            XmlAttribute LEDrule = document.CreateAttribute("rules");

            LEDrule.Value = "0x" + LEDRule.ToString("X2");
            LED.Attributes.Append(LEDrule);

            // Fan
            XmlNode FanRules = document.CreateElement("fan");

            main.AppendChild(FanRules);
            // rules
            XmlAttribute AFanRule = document.CreateAttribute("rules");

            AFanRule.Value = Enum.GetName(typeof(FanRules), FanRule);
            FanRules.Attributes.Append(AFanRule);

            // Measurement filter
            XmlNode MeasurementFilters = document.CreateElement("measurement");

            main.AppendChild(MeasurementFilters);
            // filter
            XmlAttribute AMeasurementFilter = document.CreateAttribute("filter");

            AMeasurementFilter.Value = Enum.GetName(typeof(MeasurementFilters), MeasurementFilter);
            MeasurementFilters.Attributes.Append(AMeasurementFilter);

            // Autoranging
            XmlNode Autoranging = document.CreateElement("autoranging");

            main.AppendChild(Autoranging);
            // current
            XmlAttribute CurrentAutoranging = document.CreateAttribute("current");

            CurrentAutoranging.Value = AutorangingCurrent.ToString();
            Autoranging.Attributes.Append(CurrentAutoranging);
            // voltage
            XmlAttribute VoltageAutoranging = document.CreateAttribute("voltage");

            VoltageAutoranging.Value = AutorangingVoltage.ToString();
            Autoranging.Attributes.Append(VoltageAutoranging);

            // logging settings
            XmlNode loggingPeriod = document.CreateElement("logging");

            main.AppendChild(loggingPeriod);
            XmlAttribute periodValue = document.CreateAttribute("period");

            timeConverter     = new Converters.TimeConverter(); // convert seconds to representation in time-unit
            periodValue.Value = (string)(timeConverter.Convert(logPeriod, typeof(string), logTimeUnit, System.Globalization.CultureInfo.CurrentCulture));
            loggingPeriod.Attributes.Append(periodValue);

            XmlAttribute periodTimeUnit = document.CreateAttribute("timeUnit");

            periodTimeUnit.Value = logTimeUnit.ToString();
            loggingPeriod.Attributes.Append(periodTimeUnit);

            // items
            XmlNode items = document.CreateElement("items");

            main.AppendChild(items);

            foreach (ProgramItem programItem in programItems)
            {
                XmlNode item = document.CreateElement("item");

                XmlAttribute programMode = document.CreateAttribute("programMode");
                programMode.Value = programItem.ProgramMode.ToString();
                item.Attributes.Append(programMode);

                switch (programItem.ProgramMode)
                {
                case ProgramModes.Constant:
                {
                    // parameters
                    XmlAttribute mode = document.CreateAttribute("mode");
                    mode.Value = programItem.Mode.ToString();
                    item.Attributes.Append(mode);

                    XmlAttribute value = document.CreateAttribute("value");
                    if (programItem.Value == null)
                    {
                        value.Value = "previous";
                    }
                    else
                    {
                        value.Value = programItem.Value.ToString();
                    }
                    item.Attributes.Append(value);

                    XmlAttribute duration = document.CreateAttribute("duration");
                    duration.Value = programItem.DurationString;
                    item.Attributes.Append(duration);

                    XmlAttribute timeUnit = document.CreateAttribute("timeUnit");
                    timeUnit.Value = programItem.TimeUnit.ToString();
                    item.Attributes.Append(timeUnit);
                    break;
                }

                case ProgramModes.Ramp:
                {
                    // parameters
                    XmlAttribute mode = document.CreateAttribute("mode");
                    mode.Value = programItem.Mode.ToString();
                    item.Attributes.Append(mode);

                    XmlAttribute startingValue = document.CreateAttribute("startingValue");
                    if (programItem.StartingValue == null)
                    {
                        startingValue.Value = "previous";
                    }
                    else
                    {
                        startingValue.Value = programItem.StartingValue.ToString();
                    }
                    item.Attributes.Append(startingValue);

                    XmlAttribute finalValue = document.CreateAttribute("finalValue");
                    finalValue.Value = programItem.FinalValue.ToString();
                    item.Attributes.Append(finalValue);

                    XmlAttribute duration = document.CreateAttribute("duration");
                    duration.Value = programItem.DurationString;
                    item.Attributes.Append(duration);

                    XmlAttribute timeUnit = document.CreateAttribute("timeUnit");
                    timeUnit.Value = programItem.TimeUnit.ToString();
                    item.Attributes.Append(timeUnit);
                    break;
                }

                case ProgramModes.Pin:
                {
                    XmlAttribute pinNumber = document.CreateAttribute("pinLogicalNumber");
                    pinNumber.Value = programItem.Pin < Load.Pins.Length ? programItem.Pin.ToString() : "all";
                    item.Attributes.Append(pinNumber);

                    XmlAttribute action = document.CreateAttribute("action");
                    action.Value = programItem.SetUserPin ? "set" : "reset";
                    item.Attributes.Append(action);
                    break;
                }
                }

                // skip attributes
                if (programItem.SkipEnabled)
                {
                    XmlNode      skip     = document.CreateElement("skip");
                    XmlAttribute skipMode = document.CreateAttribute("mode");
                    skipMode.Value = programItem.SkipMode.ToString();
                    skip.Attributes.Append(skipMode);
                    XmlAttribute skipComparator = document.CreateAttribute("comparator");
                    skipComparator.Value = programItem.SkipComparator.ToString();
                    skip.Attributes.Append(skipComparator);
                    XmlAttribute skipValue = document.CreateAttribute("value");
                    skipValue.Value = programItem.SkipValue.ToString();
                    skip.Attributes.Append(skipValue);
                    item.AppendChild(skip);
                }

                items.AppendChild(item);
            }

            document.Save(path);
        }
Ejemplo n.º 7
0
        // creates Xml file with program items, loop info, local/remote info and period settings
        public void SaveItems(BindingList <ProgramItem> programItems, bool loopIsEnabled, int loopCount, bool isRemote, double logPeriod, TimeUnits logTimeUnit)
        {
            XmlNode declaration = document.CreateXmlDeclaration("1.0", "UTF-8", null);

            document.AppendChild(declaration);
            XmlNode comment = document.CreateComment("MightyWatt experiment settings");

            document.AppendChild(comment);
            XmlElement main = document.CreateElement("settings");

            document.AppendChild(main);

            if (loopIsEnabled == true)
            {
                // loop settings
                XmlNode loop = document.CreateElement("loop");

                // duration
                XmlAttribute count = document.CreateAttribute("count");
                if (loopCount < 0)
                {
                    count.Value = "infinite";
                }
                else
                {
                    count.Value = loopCount.ToString();
                }
                loop.Attributes.Append(count);
                main.AppendChild(loop);
            }

            // local/remote settings
            XmlNode remote = document.CreateElement("voltageSenseMode");

            main.AppendChild(remote);
            // is remote
            XmlAttribute isrem = document.CreateAttribute("isRemote");

            isrem.Value = isRemote.ToString();
            remote.Attributes.Append(isrem);

            // logging settings
            XmlNode loggingPeriod = document.CreateElement("logging");

            main.AppendChild(loggingPeriod);
            XmlAttribute periodValue = document.CreateAttribute("period");

            timeConverter     = new Converters.TimeConverter(); // convert seconds to representation in time-unit
            periodValue.Value = (string)(timeConverter.Convert(logPeriod, typeof(string), logTimeUnit, System.Globalization.CultureInfo.CurrentCulture));
            loggingPeriod.Attributes.Append(periodValue);

            XmlAttribute periodTimeUnit = document.CreateAttribute("timeUnit");

            periodTimeUnit.Value = logTimeUnit.ToString();
            loggingPeriod.Attributes.Append(periodTimeUnit);

            // items
            XmlNode items = document.CreateElement("items");

            main.AppendChild(items);

            foreach (ProgramItem programItem in programItems)
            {
                XmlNode item = document.CreateElement("item");

                XmlAttribute programMode = document.CreateAttribute("programMode");
                programMode.Value = programItem.ProgramMode.ToString();
                item.Attributes.Append(programMode);

                // parameters
                XmlAttribute mode = document.CreateAttribute("mode");
                mode.Value = programItem.Mode.ToString();
                item.Attributes.Append(mode);

                switch (programItem.ProgramMode)
                {
                case ProgramModes.Constant:
                {
                    XmlAttribute value = document.CreateAttribute("value");
                    if (programItem.Value == null)
                    {
                        value.Value = "previous";
                    }
                    else
                    {
                        value.Value = programItem.Value.ToString();
                    }
                    item.Attributes.Append(value);
                    break;
                }

                case ProgramModes.Ramp:
                {
                    XmlAttribute startingValue = document.CreateAttribute("startingValue");
                    if (programItem.StartingValue == null)
                    {
                        startingValue.Value = "previous";
                    }
                    else
                    {
                        startingValue.Value = programItem.StartingValue.ToString();
                    }
                    item.Attributes.Append(startingValue);

                    XmlAttribute finalValue = document.CreateAttribute("finalValue");
                    finalValue.Value = programItem.FinalValue.ToString();
                    item.Attributes.Append(finalValue);
                    break;
                }
                }

                XmlAttribute duration = document.CreateAttribute("duration");
                duration.Value = programItem.DurationString;
                item.Attributes.Append(duration);

                XmlAttribute timeUnit = document.CreateAttribute("timeUnit");
                timeUnit.Value = programItem.TimeUnit.ToString();
                item.Attributes.Append(timeUnit);

                // skip attributes
                if (programItem.SkipEnabled)
                {
                    XmlNode      skip     = document.CreateElement("skip");
                    XmlAttribute skipMode = document.CreateAttribute("mode");
                    skipMode.Value = programItem.SkipMode.ToString();
                    skip.Attributes.Append(skipMode);
                    XmlAttribute skipComparator = document.CreateAttribute("comparator");
                    skipComparator.Value = programItem.SkipComparator.ToString();
                    skip.Attributes.Append(skipComparator);
                    XmlAttribute skipValue = document.CreateAttribute("value");
                    skipValue.Value = programItem.SkipValue.ToString();
                    skip.Attributes.Append(skipValue);
                    item.AppendChild(skip);
                }

                items.AppendChild(item);
            }

            document.Save(path);
        }