internal void OnConnect() { m_Channel.AcquisitionStateProperty.Update((int)AcquisitionState.Idle); // read this from the hardware m_WavelengthProperty.Update(m_WaveLength); }
void m_dcr_OnSetProperty(SetPropertyEventArgs args) { SetDoublePropertyEventArgs dblArgs = args as SetDoublePropertyEventArgs; if (dblArgs != null) { m_dcr.Update(dblArgs.NewValue); } }
/// <summary> /// We use the OnDataFinished event to stop data acquisition. /// When CM sends this event enough data has already been sent and we can stop immediately. /// </summary> /// <param name="args"></param> void m_MyCmDevice_OnDataFinished(DataFinishedEventArgs args) { if (m_Timer != null) { m_GotDataFinished = true; m_SpectraIndexProperty.Update(null); m_ChannelTimeProperty.Update(null); } }
void m_RateProperty_OnSetProperty(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doubleArgs = args as SetDoublePropertyEventArgs; m_RateProperty.Update(doubleArgs.NewValue); // For the time stamped channel rate and timestep are different. // The rate determines at which rate data points are to be sent; // The timestep determines how the timestamps are encoded. }
public PumpProperties(IDDK ddk, IDevice device) { if (ddk == null) { throw new ArgumentNullException("ddk"); } if (device == null) { throw new ArgumentNullException("device"); } Ready = Property.CreateReady(ddk, device); // Pressure.LowerLimit // Pressure.UpperLimit // Pressure.Value m_Pressure = device.CreateStruct("Pressure", "The pump pressure."); ITypeDouble pressureType = ddk.CreateDouble(0, 400, 3); pressureType.Unit = UnitConversionEx.PhysUnitName(UnitConversion.PhysUnitEnum.PhysUnit_Bar); PressureValue = m_Pressure.CreateStandardProperty(StandardPropertyID.Value, pressureType); PressureValue.Update(0); PressureLowerLimit = m_Pressure.CreateStandardProperty(StandardPropertyID.LowerLimit, pressureType); PressureLowerLimit.Update(pressureType.Minimum); PressureUpperLimit = m_Pressure.CreateStandardProperty(StandardPropertyID.UpperLimit, pressureType); PressureUpperLimit.Update(pressureType.Maximum); m_Pressure.DefaultGetProperty = PressureValue; }
private void OnSetPressureUpperLimit(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doubleArgs = args as SetDoublePropertyEventArgs; m_Device.AuditMessage(AuditLevel.Normal, "Pressure.UpperLimit is set to " + doubleArgs.NewValue.Value.ToString() + " bar"); m_PressureUpperLimit.Update(doubleArgs.NewValue.Value); }
void m_MyDoubleProperty_OnSetProperty(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doubleArgs = args as SetDoublePropertyEventArgs; Double?newValue = doubleArgs.NewValue; m_MyDoubleProperty.Update(doubleArgs.NewValue); }
public ChannelProperties(IDDK ddk, IChannel channel) { if (ddk == null) { throw new ArgumentNullException("ddk"); } if (channel == null) { throw new ArgumentNullException("channel"); } ITypeDouble typeDouble = Property.CreateDoubleType(ddk, UnitConversion.PhysUnitEnum.PhysUnit_Hertz, 0.1, 1000, 1); Rate = channel.CreateProperty("Rate", "The data collection rate in " + typeDouble.Unit, typeDouble); Rate.Update(100); typeDouble = Property.CreateDoubleType(ddk, UnitConversion.PhysUnitEnum.PhysUnit_NanoMeter, 200, 400, 1); Wavelength = channel.CreateStandardProperty(StandardPropertyID.Wavelength, typeDouble); AcquisitionTimeOn = Property.CreateString(ddk, channel, "AcquisitionTime_1_On"); AcquisitionTimeOff = Property.CreateString(ddk, channel, "AcquisitionTime_2_Off"); AcquisitionTimeDiff = Property.CreateString(ddk, channel, "AcquisitionTime_3_Diff"); // Make the property available as a report variable. This is stored with the signal as meta data. channel.AddPropertyToChannelInfo(Rate); channel.AddPropertyToChannelInfo(Wavelength); }
void m_RateProperty_OnSetProperty(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doubleArgs = args as SetDoublePropertyEventArgs; m_RateProperty.Update(doubleArgs.NewValue); // Our rate determines TimeStepFactorProperty and TimeStepDivisorProperty: // TimeStepDivisorProperty / TimeStepFactorProperty = RateProperty /100 Hz // TimeStepFactorProperty and TimeStepDivisorProperty must be integers. // To keep it simple we set TimeStepFactorProperty = 10000 and calcutate // TimeStepDivisorProperty from the rate: // TimeStepDivisorProperty = RateProperty * 100 m_MyCmDevice.TimeStepDivisorProperty.Update( (int)(doubleArgs.NewValue.Value * 100.0)); m_MyCmDevice.TimeStepFactorProperty.Update(10000); }
void genericHandler(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doubleArgs = args as SetDoublePropertyEventArgs; Double? newValue = doubleArgs.NewValue; IDoubleProperty doubleProperty = args.Property as IDoubleProperty; doubleProperty.Update(doubleArgs.NewValue); }
internal void Connect() { // initialize our properties m_MyCmDevice.TimeStepFactorProperty.Update(100); m_MyCmDevice.TimeStepDivisorProperty.Update(60); m_MyCmDevice.AcquisitionStateProperty.Update((int)AcquisitionState.Idle); m_WavelengthProperty.Update(200.0); }
internal void Create(IDDK cmDDK, string deviceName) { m_DDK = cmDDK; m_Device = m_DDK.CreateDevice(deviceName, "Pump device"); IStringProperty typeProperty = m_Device.CreateProperty("DeviceType", "The DeviceType property tells us which component we are talking to.", m_DDK.CreateString(20)); typeProperty.Update("Pump"); // A data type for our pump flow ITypeDouble tFlow = m_DDK.CreateDouble(0, 10, 1); tFlow.Unit = "ml/min"; // Create our flow handler. The flow handler creates a Flow.Nominal, // a Flow.Value and 4 eluent component properties for us. m_FlowHandler = m_Device.CreateFlowHandler(tFlow, 4, 2); m_FlowHandler.FlowNominalProperty.OnSetProperty += OnSetFlow; // initialize the flow m_FlowHandler.FlowNominalProperty.Update(0); // initialize the components m_FlowHandler.ComponentProperties[0].Update(100.0); m_FlowHandler.ComponentProperties[1].Update(0); m_FlowHandler.ComponentProperties[2].Update(0); m_FlowHandler.ComponentProperties[3].Update(0); // A type for our pump pressure ITypeDouble tPressure = m_DDK.CreateDouble(0, 400, 1); tPressure.Unit = "bar"; // We create a struct for the pressure with Value, LowerLimit and UpperLimit m_PressureStruct = m_Device.CreateStruct("Pressure", "The pump pressure."); m_PressureValue = m_PressureStruct.CreateStandardProperty(StandardPropertyID.Value, tPressure); m_PressureLowerLimit = m_PressureStruct.CreateStandardProperty(StandardPropertyID.LowerLimit, tPressure); m_PressureLowerLimit.OnSetProperty += new SetPropertyEventHandler(OnSetPressureLowerLimit); m_PressureLowerLimit.Update(0.0); m_PressureUpperLimit = m_PressureStruct.CreateStandardProperty(StandardPropertyID.UpperLimit, tPressure); m_PressureUpperLimit.OnSetProperty += new SetPropertyEventHandler(OnSetPressureUpperLimit); m_PressureUpperLimit.Update(400.0); m_PressureStruct.DefaultGetProperty = m_PressureValue; m_Device.OnTransferPreflightToRun += new PreflightEventHandler(OnTransferPreflightToRun); }
private void OnSetTemperature(SetPropertyEventArgs args) { SetDoublePropertyEventArgs doublePropertyArgs = args as SetDoublePropertyEventArgs; Debug.Assert(doublePropertyArgs.NewValue.HasValue); m_NominalTempProperty.Update(doublePropertyArgs.NewValue.Value); // A real hardware would need some time to reach the new temperature. Thread.Sleep(1000); m_CurrentTempProperty.Update(doublePropertyArgs.NewValue.Value); }
/// <summary> /// OnConnect we set up some initial values. /// In a real driver, OnConnect would establish the hardware connection first and /// retrieve the actual hardware status from the hardware. /// </summary> internal void OnConnect() { // Write a message to the audit trail m_MyCmDevice.AuditMessage(AuditLevel.Message, "ExampleDevice.OnConnect()"); // set up the initial values m_EnableClockProperty.Update(0); m_MyString = "Initial value"; // Send the updated string to Chromeleon. m_AnyTextProperty.Update(m_MyString); m_Percentage = 11.11; // Send the updated percentage to Chromeleon. m_PercentageProperty.Update(m_Percentage); // Update the other properties m_FilterTimeConstantProperty.Update(0.0); m_MeasurementRangeProperty.Update(10.0); }
/// <summary> /// Create our Dionex.Chromeleon.Symbols.IDevice and our Properties and Commands /// </summary> /// <param name="cmDDK">The DDK instance</param> /// <param name="name">The name for our device</param> /// <returns>our IDevice object</returns> internal IDevice Create(IDDK cmDDK, string name) { // Create our Dionex.Chromeleon.Symbols.IDevice m_MyCmDevice = cmDDK.CreateDevice(name, "This is my first DDK device."); m_MyStringProperty = m_MyCmDevice.CreateProperty("MyStringProperty", "A string property", cmDDK.CreateString(5)); m_MyStringProperty.OnSetProperty += new SetPropertyEventHandler(m_MyStringProperty_OnSetProperty); m_MyStringProperty.OnPreflightSetProperty += m_MyStringProperty_OnPreflightSetProperty; // Create a Property of type double. m_MyDoubleProperty = m_MyCmDevice.CreateProperty("MyDoubleProperty", "This is my first property", cmDDK.CreateDouble(0, 20, 2)); // Set the property to writable. m_MyDoubleProperty.Writeable = true; // And provide a handler that gets called when the property is assigned. m_MyDoubleProperty.OnSetProperty += new SetPropertyEventHandler(m_MyDoubleProperty_OnSetProperty); // Update all properties that have to be readable before the device is connected. m_MyDoubleProperty.Update(20.0); // Create a Property of type int. m_MyIntProperty = m_MyCmDevice.CreateProperty("MyIntProperty", "This is my second property", cmDDK.CreateInt(-1, 2)); // Set the property to read-only. m_MyIntProperty.Writeable = false; // No value known until the device is connected. m_MyIntProperty.Update(null); CreateMoreProperties(cmDDK); return(m_MyCmDevice); }
internal void Create(IDDK cmDDK, string deviceName) { m_DDK = cmDDK; ITypeInt tSignal = m_DDK.CreateInt(0, 1000); tSignal.Unit = "mAU"; m_Channel = m_DDK.CreateChannel(deviceName, "Detector device", tSignal); IStringProperty typeProperty = m_Channel.CreateProperty("DeviceType", "The DeviceType property tells us which component we are talking to.", m_DDK.CreateString(20)); typeProperty.Update("Detector"); m_Channel.AcquisitionOffCommand.OnCommand += new CommandEventHandler(OnAcqOff); m_Channel.AcquisitionOnCommand.OnCommand += new CommandEventHandler(OnAcqOn); ITypeDouble tWavelength = m_DDK.CreateDouble(200, 400, 1); tWavelength.Unit = "nm"; m_WavelengthProperty = m_Channel.CreateStandardProperty(StandardPropertyID.Wavelength, tWavelength); m_WavelengthProperty.OnSetProperty += new SetPropertyEventHandler(OnSetWaveLength); // We want to have the wavelength available as a report variable and therefore add it to the channel info. m_Channel.AddPropertyToChannelInfo(m_WavelengthProperty); m_WavelengthProperty.Update(m_WaveLength); // What do we actually measure? m_Channel.PhysicalQuantity = "Absorbance"; m_Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); }
/// Create our Dionex.Chromeleon.Symbols.IDevice and our Properties internal IDevice Create(IDDK cmDDK, string name) { // Create a device for temperature control m_Device = cmDDK.CreateDevice(name, "Example for a temperature control device"); // Create a type for a temperature logging command ITypeInt tyTempLogParam = cmDDK.CreateInt(0, 2); tyTempLogParam.AddNamedValue("Start", 0); tyTempLogParam.AddNamedValue("Stop", 1); tyTempLogParam.AddNamedValue("Pause", 2); // Create a temperature logging command ICommand logTemperature = m_Device.CreateCommand("LogTemperature", "Switches temperature logging on / off"); // Add a parameter for the tewmperature logging command logTemperature.AddParameter("LogParameter", "Starts, stops or pauses temperature logging", tyTempLogParam); // Create a boolean property to signal if the device is ready for an inject operation. ITypeInt tyReady = cmDDK.CreateInt(0, 1); tyReady.AddNamedValue("False", 0); tyReady.AddNamedValue("True", 1); IProperty readyProp = m_Device.CreateStandardProperty(StandardPropertyID.Ready, tyReady); // Create a data type that represent the activation state of the temperature control. ITypeInt tOnOff = cmDDK.CreateInt((int)TempCtrlState.Off, (int)TempCtrlState.On); tOnOff.AddNamedValue("Off", (int)TempCtrlState.Off); tOnOff.AddNamedValue("On", (int)TempCtrlState.On); // Create a property to activate / deactivate temperature control // This property must be writable m_TempCtrlProperty = m_Device.CreateProperty("TemperatureControl", "Activates /deactivates temperature control", tOnOff); m_TempCtrlProperty.Writeable = true; // Create a struct that holds standard properties for temperature and temperature limits m_TempCtrlStruct = m_Device.CreateStruct("Temperature", "Temperature of Column Oven."); // Create a data type that applies to all temperature properties ITypeDouble tTemperature = cmDDK.CreateDouble(0, 100, 1); tTemperature.Unit = "°C"; // Create a property that holds the current temperature // This property is read-only m_CurrentTempProperty = m_TempCtrlStruct.CreateStandardProperty(StandardPropertyID.Value, tTemperature); // Create a property that holds the nominal temperature // This property must be writeable m_NominalTempProperty = m_TempCtrlStruct.CreateStandardProperty(StandardPropertyID.Nominal, tTemperature); m_NominalTempProperty.Update(30.0); //set default value m_NominalTempProperty.OnSetProperty += new SetPropertyEventHandler(OnSetTemperature); // Create a property that holds the minimal temperature // This property must be writeable m_MinTempProperty = m_TempCtrlStruct.CreateStandardProperty(StandardPropertyID.LowerLimit, tTemperature); m_MinTempProperty.Update(15.0); //set default value m_MinTempProperty.Writeable = true; // Create a property that holds the maximal temperature // This property must be writeable m_MaxTempProperty = m_TempCtrlStruct.CreateStandardProperty(StandardPropertyID.UpperLimit, tTemperature); m_MaxTempProperty.Update(110.0);//set default value m_MaxTempProperty.Writeable = true; // Set the default read and write properties for the struct m_TempCtrlStruct.DefaultSetProperty = m_NominalTempProperty; m_TempCtrlStruct.DefaultGetProperty = m_CurrentTempProperty; // Update property values. They must be readable before the device has been connected. // The device may not be connected when UI-Modules read the default values. m_TempCtrlProperty.Update((int)m_TempCtrl); m_NominalTempProperty.Update(m_NominalTemp); m_MinTempProperty.Update(m_MinTemp); m_MaxTempProperty.Update(m_MaxTemp); m_CurrentTempProperty.Update(m_CurrentTemp); return(m_Device); }
internal void OnConnect() { // Update these values from the hardware m_FlowHandler.FlowValueProperty.Update(0.0); m_PressureValue.Update(0.0); }
/// <summary> /// This illustrates variations on the ITypeDouble that can be used for creating properties /// </summary> internal void CreateMoreProperties(IDDK cmDDK) { ITypeDouble type1 = cmDDK.CreateDouble(-1, 1, 0); // Range: [-1...1] // - any number -1 <= x <= 1 can be assigned, will be rounded to 0 decimals // - user input is allowed with 0 decimals only (-1|0|1) // - numbers outside this range (-1|0|1) cause validation errors in panel edit controls or during Instrument Method syntax checking // - panel edit control's spin box will spin -1,0,1 // - F8 box's/Instrument Method Editor's drop list will contain -1,0,1 IDoubleProperty type1Property = m_MyCmDevice.CreateProperty("Type1Property", "", type1); type1Property.Update(-1); //set default value type1Property.OnSetProperty += new SetPropertyEventHandler(type1Property_OnSetProperty); ITypeDouble type2 = cmDDK.CreateDouble(-1, 1, 2); type2.Unit = "bar"; // Range: [-1.00..1.00 bar] // - any number -1 <= x <= 1 can be assigned, will be rounded to 2 decimals // - user input is allowed with up to 2 decimals // - numbers outside this range cause validation errors in panel edit controls or during Instrument Method syntax checking // - unit "bar" is shown in Commands overview (F8), // and can be appended to text shown in panel edit controls and panel string displays // - unit [bar] can be added to assignments in Instrument Method scripts, // system can also convert from other units if it makes sense, // e.g. Type2Property = 1 [psi] is equal to Type2Property = 0.0689475729 [bar] // - panel edit control's spin box will spin in 0.01 incrementals // - F8 box's/Instrument Method Editor's drop list will be empty as it would be too long (a maximum of 12 items can be shown) IDoubleProperty type2Property = m_MyCmDevice.CreateProperty("Type2Property", "", type2); type2Property.Update(0.0); //set default value type2Property.OnSetProperty += new SetPropertyEventHandler(type2Property_OnSetProperty); ITypeDouble type3 = cmDDK.CreateDouble(0, 20, 1); type3.AddNamedValue("Null", 0); type3.AddNamedValue("OnePointFive", 1.5); type3.AddNamedValue("Ten", 10); type3.AddNamedValue("Thirty", 30); // Range: [Null..20.0] - when a property is displayed or logged, a named value is used instead of a pure number if a named value is available. // - any number 0 <= x <= 20 can be assigned, will be rounded to 1 decimal // - 30 can also be assigned, even if it is outside the min/max range, because it has been added as named value // - user input is allowed with up to 1 decimal // - instead of Type3Property = 0, one can write Type3Property = Null // - instead of Type3Property = 1.5, one can write Type3Property = OnePointFive // - instead of Type3Property = 10, one can write Type3Property = Ten // - instead of Type3Property = 30, one can write Type3Property = Thirty // - panel edit control's spin box will spin in 0.1 incrementals: Null, 0.1, 0.2, ..., 1.4, OnePointFive, 1.6, .... 20.0, Thirty // - F8 box's/Instrument Method Editor's drop list contains the four named values IDoubleProperty type3Property = m_MyCmDevice.CreateProperty("Type3Property", "", type3); type3Property.Update(4);//set default value type3Property.OnSetProperty += new SetPropertyEventHandler(type3Property_OnSetProperty); ITypeDouble type4 = cmDDK.CreateDouble(0, 20, 1); type4.AddNamedValue("Null", 0); type4.AddNamedValue("Ten", 10); type4.AddNamedValue("Twenty", 20); type4.NamedValuesOnly = true; // Range: [Null..Twenty] - when a property is displayed or logged, a named value is used instead of a pure number if a named value is available. // - numbers 0.0, 10.0 and 20.0 can be assigned only, because of the 'NamedValuesOnly' flag. // - instead of Type3Property = 0, one can write Type3Property = Null // - instead of Type3Property = 10, one can write Type3Property = Ten // - instead of Type3Property = 20, one can write Type3Property = Twenty // - panel edit control's spin box will spin Null, Ten, Twenty only. Other values will cause validation errors // - F8 box's/Instrument Method Editor's drop list contains the three named values, other values will cause validation errors IDoubleProperty type4Property = m_MyCmDevice.CreateProperty("Type4Property", "", type4); type4Property.Update(0);//set default value type4Property.OnSetProperty += new SetPropertyEventHandler(type4Property_OnSetProperty); ITypeDouble type5 = cmDDK.CreateDouble(0, 20, 1); Double[] legalValues = { 1.1, 2.2, 3.3 }; type5.LegalValues = legalValues; // Range: [0.0..20.0] // - any (!) number 0 <= x <= 20 can be assigned, will be rounded to 1 decimal // - user input is allowed with up to 1 decimal // - panel edit control's spin box will spin to 1.1, 2.2 and 3.3 (due to LegalValues) // - F8 box's/Instrument Method Editor's drop list contains the three legal values IDoubleProperty type5Property = m_MyCmDevice.CreateProperty("Type5Property", "", type5); type5Property.Update(2.2);//set default value type5Property.OnSetProperty += new SetPropertyEventHandler(type5Property_OnSetProperty); ITypeDouble type6 = cmDDK.CreateDouble(0, 20, 1); type6.LegalValues = legalValues; type6.AddNamedValue("Null", 0); type6.AddNamedValue("OnePointFive", 1.5); type6.AddNamedValue("Ten", 10); type6.AddNamedValue("Twenty", 20); // Range: [Null..20.0] // - any (!) number 0 <= x <= 20 can be assigned, will be rounded to 1 decimal // - user input is allowed with up to 1 decimal // - panel edit control's spin box will spin to all legal and named values // - F8 box's/Instrument Method Editor's drop list contains the seven legal and named values IDoubleProperty type6Property = m_MyCmDevice.CreateProperty("Type6Property", "", type6); type6Property.Update(10);//set default value type6Property.OnSetProperty += new SetPropertyEventHandler(type6Property_OnSetProperty); ITypeInt badBooleanType = cmDDK.CreateInt(0, 1); IIntProperty badBoolean1 = m_MyCmDevice.CreateProperty("BadBoolean", "This is a Boolean type without enumerations. Please define appropriate enumerations in the driver!", badBooleanType); badBoolean1.OnSetProperty += new SetPropertyEventHandler(badBoolean_OnSetProperty); m_MyProperBoolean = m_MyCmDevice.CreateBooleanProperty("ProperBoolean", "This is how to do it", "False_No_Zero_NotReady", "True_Yes_One_Ready"); m_MyProperBoolean.OnSetProperty += new SetPropertyEventHandler(properBoolean_OnSetProperty); ITypeInt explicitBooleanType = cmDDK.CreateInt(0, 1); explicitBooleanType.AddNamedValue("False_No_Zero_NotReady", 0); explicitBooleanType.AddNamedValue("True_Yes_One_Ready", 1); explicitBooleanType.NamedValuesOnly = true; IIntProperty explicitBoolean = m_MyCmDevice.CreateProperty("ExplicitBoolean", "Also ok, but way more explicit code", explicitBooleanType); explicitBoolean.OnSetProperty += new SetPropertyEventHandler(explicitBoolean_OnSetProperty); }
public HeaterProperties(IDDK ddk, Config.Heater config, IDevice device) { if (ddk == null) { throw new ArgumentNullException("ddk"); } if (config == null) { throw new ArgumentNullException("config"); } if (device == null) { throw new ArgumentNullException("device"); } Ready = Property.CreateReady(ddk, device); m_Product = device.CreateStruct("Product", "Product Help Text"); m_ProductName = Property.CreateString(ddk, m_Product, "Name"); m_ProductName.Writeable = true; m_ProductName.Update("Product Name"); m_ProductDescription = Property.CreateString(ddk, m_Product, "Description"); m_ProductDescription.Update(config.ProductDescription); // Set the default read and write properties for the structure - optional m_Product.DefaultGetProperty = m_ProductName; m_Product.DefaultSetProperty = m_ProductName; Power = Property.CreateDouble(ddk, device, "Power", UnitConversion.PhysUnitEnum.PhysUnit_Watt, null, 0); // the unit W is localized // Temperature.Control - On/Off // Temperature.LowerLimit // Temperature.UpperLimit // Temperature.Nominal // Temperature.Value m_Temperature = device.CreateStruct("Temperature", "Heater Temperature"); TemperatureControl = Property.CreateEnum(ddk, m_Temperature, "Control", Heater.TemperatureControl.Off); TemperatureControl.Writeable = true; string temperatureUnit = UnitConversionEx.PhysUnitName(UnitConversion.PhysUnitEnum.PhysUnit_Celsius); // °C - localized const int temperaturePrecision = 1; ITypeDouble temperatureType = ddk.CreateDouble(0, 100, temperaturePrecision); temperatureType.Unit = temperatureUnit; TemperatureMin = m_Temperature.CreateStandardProperty(StandardPropertyID.LowerLimit, temperatureType); TemperatureMin.Writeable = true; TemperatureMin.Update(20); TemperatureMax = m_Temperature.CreateStandardProperty(StandardPropertyID.UpperLimit, temperatureType); TemperatureMax.Writeable = true; TemperatureMax.Update(80); TemperatureNominal = m_Temperature.CreateStandardProperty(StandardPropertyID.Nominal, temperatureType); // Desired (requested) temperature TemperatureNominal.Writeable = true; TemperatureNominal.Update(50); temperatureType = ddk.CreateDouble(double.MinValue, double.MaxValue, temperaturePrecision); temperatureType.Unit = temperatureUnit; TemperatureValue = m_Temperature.CreateStandardProperty(StandardPropertyID.Value, temperatureType); TemperatureValue.Update(40); // Set the default read and write properties for the structure m_Temperature.DefaultGetProperty = TemperatureValue; m_Temperature.DefaultSetProperty = TemperatureNominal; }