/// <summary> /// Synchronise the DeviceZone information in the OPC UA information model with the current state of a /// Temperature Control Device simulator. For read-write fields the synchronisation is bidirectional: if the /// simulator indicates that the value has changed, then the OPC UA information model is updated; otherwise /// if the value in the information model is different from that in the simulator, then the simulator is /// upated with the new value. Read-only fields are updated from the simulator if the value has changed. /// </summary> /// <param name="simulator">The simulator to sync with.</param> public void SyncWith(TCDSimulator simulator) { // Update Temperature.ActualValue. double actualTemp = simulator.GetActualTemp_C(); if (!(m_temperature.ActualValue.Value is double) || (double)m_temperature.ActualValue.Value != actualTemp) { m_temperature.ActualValue.Value = actualTemp; if (m_temperature.ActualValue.EngineeringUnits == null) { m_temperature.ActualValue.EngineeringUnits = new PropertyState <EUInformation>(m_temperature.ActualValue); } m_temperature.ActualValue.EngineeringUnits.Value = new EUInformation("C", "Degrees Centigrade", @"http://www.opcfoundation.org/UA/units/un/cefact"); m_temperature.ActualValue.UpdateChangeMasks(NodeStateChangeMasks.Value); } // Synchronise Temperature.SetValue. double setpoint = simulator.GetSetpoint_C(); if (simulator.HasSetpointChanged()) { m_temperature.SetValue.Value = setpoint; m_temperature.SetValue.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.SetValue.Value is double && (double)m_temperature.SetValue.Value != setpoint) { simulator.SetSetpoint((double)m_temperature.SetValue.Value, true); } // Synchronise Temperature.SetRampUp. double rampUp = simulator.GetRampUp_CpMin(); if (simulator.HasRampUpChanged()) { m_temperature.SetRampUp.Value = rampUp; m_temperature.SetRampUp.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.SetRampUp.Value is double && (double)m_temperature.SetRampUp.Value != rampUp) { simulator.SetRampUp((double)m_temperature.SetRampUp.Value, true); } // Synchronise Temperature.SetRampDown. double rampDown = simulator.GetRampDown_CpMin(); if (simulator.HasRampDownChanged()) { m_temperature.SetRampDown.Value = rampDown; m_temperature.SetRampDown.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.SetRampDown.Value is double && (double)m_temperature.SetRampDown.Value != rampDown) { simulator.SetRampDown((double)m_temperature.SetRampDown.Value, true); } // Synchronise Temperature.LowerTolerance. double lowerTolerance = simulator.GetLowerTolerance_C(); if (simulator.HasLowerToleranceChanged()) { m_temperature.LowerTolerance.Value = lowerTolerance; m_temperature.LowerTolerance.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.LowerTolerance.Value is double && (double)m_temperature.LowerTolerance.Value != lowerTolerance) { simulator.SetLowerTolerance((double)m_temperature.LowerTolerance.Value, true); } // Synchroise Temperature.UpperTolerance. double upperTolerance = simulator.GetUpperTolerance_C(); if (simulator.HasUpperToleranceChanged()) { m_temperature.UpperTolerance.Value = upperTolerance; m_temperature.UpperTolerance.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.UpperTolerance.Value is double && (double)m_temperature.UpperTolerance.Value != upperTolerance) { simulator.SetUpperTolerance((double)m_temperature.UpperTolerance.Value, true); } // Synchronise Temperature.MinValue. double minValue = simulator.GetMinValue_C(); if (simulator.HasMinValueChanged()) { m_temperature.MinValue.Value = minValue; m_temperature.MinValue.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.MinValue.Value is double && (double)m_temperature.MinValue.Value != minValue) { simulator.SetMinValue((double)m_temperature.MinValue.Value, true); } // Synchronise Temperature.MaxValue. double maxValue = simulator.GetMaxValue_C(); if (simulator.HasMaxValueChanged()) { m_temperature.MaxValue.Value = maxValue; m_temperature.MaxValue.UpdateChangeMasks(NodeStateChangeMasks.Value); } else if (m_temperature.MaxValue.Value is double && (double)m_temperature.MaxValue.Value != maxValue) { simulator.SetMaxValue((double)m_temperature.MaxValue.Value, true); } if (m_maintenanceInformation != null) { // Synchronise MaintenanceInformation Cooling. if (m_maintenanceInformation.Cooling != null) { m_maintenanceInformation.Cooling.SyncWith(simulator.CoolingMaintenance); if (!(m_maintenanceInformation.Cooling.Reset is ResetCoolingMaintenanceMethodState)) { ResetCoolingMaintenanceMethodState method = new ResetCoolingMaintenanceMethodState(m_maintenanceInformation.Cooling.Reset); method.setSimulator(simulator); m_maintenanceInformation.Cooling.Reset = method; } } // Synchronise MaintenanceInformation Heating. if (m_maintenanceInformation.Heating != null) { m_maintenanceInformation.Heating.SyncWith(simulator.HeatingMaintenance); if (!(m_maintenanceInformation.Heating.Reset is ResetHeatingMethodState)) { ResetHeatingMethodState method = new ResetHeatingMethodState(m_maintenanceInformation.Heating.Reset); method.setSimulator(simulator); m_maintenanceInformation.Heating.Reset = method; } } } }