/// <summary> /// Indicates if it is a special plextor card /// </summary> /// <returns>true, if it is a special plextor card</returns> public void PerformTune(AnalogChannel channel) { if (_currentChannel != null) { bool updateRequired = _currentChannel.IsTv == channel.IsTv; if (updateRequired || (_currentChannel.VideoSource != channel.VideoSource && _videoPinMap.ContainsKey(channel.VideoSource))) { _crossBarFilter.Route(_videoOutPinIndex, _videoPinMap[channel.VideoSource]); updateRequired = true; } if (_audioOutPinIndex == -1) { return; } if (updateRequired || _currentChannel.AudioSource != channel.AudioSource) { if (channel.AudioSource == AnalogChannel.AudioInputType.Automatic && _videoPinRelatedAudioMap.ContainsKey(channel.VideoSource)) { _crossBarFilter.Route(_audioOutPinIndex, _videoPinRelatedAudioMap[channel.VideoSource]); } else if (_audioPinMap.ContainsKey(channel.AudioSource)) { _crossBarFilter.Route(_audioOutPinIndex, _audioPinMap[channel.AudioSource]); } } } else { if (_videoPinMap.ContainsKey(channel.VideoSource)) { _crossBarFilter.Route(_videoOutPinIndex, _videoPinMap[channel.VideoSource]); } if (_audioOutPinIndex == -1) { return; } if (channel.AudioSource == AnalogChannel.AudioInputType.Automatic && _videoPinRelatedAudioMap.ContainsKey(channel.VideoSource)) { _crossBarFilter.Route(_audioOutPinIndex, _videoPinRelatedAudioMap[channel.VideoSource]); } else if (_audioPinMap.ContainsKey(channel.AudioSource)) { _crossBarFilter.Route(_audioOutPinIndex, _audioPinMap[channel.AudioSource]); } } _currentChannel = channel; }
private void PerformTuning(IChannel channel) { Log.Log.WriteFile("HDPVR: Tune"); AnalogChannel analogChannel = channel as AnalogChannel; if (analogChannel == null) { throw new NullReferenceException(); } // Set up the crossbar. IAMCrossbar crossBarFilter = _filterCrossBar as IAMCrossbar; // Video if ((_previousChannel == null || _previousChannel.VideoSource != analogChannel.VideoSource) && _videoPinMap.ContainsKey(analogChannel.VideoSource)) { Log.Log.WriteFile("HDPVR: video input -> {0}", analogChannel.VideoSource); crossBarFilter.Route(_videoOutPinIndex, _videoPinMap[analogChannel.VideoSource]); } // Audio if (analogChannel.AudioSource == AnalogChannel.AudioInputType.Automatic) { if (_videoPinRelatedAudioMap.ContainsKey(analogChannel.VideoSource)) { Log.Log.WriteFile("HDPVR: audio input -> (auto)"); crossBarFilter.Route(_audioOutPinIndex, _videoPinRelatedAudioMap[analogChannel.VideoSource]); } } else if ((_previousChannel == null || _previousChannel.AudioSource != analogChannel.AudioSource) && _audioPinMap.ContainsKey(analogChannel.AudioSource)) { Log.Log.WriteFile("HDPVR: audio input -> {0}", analogChannel.AudioSource); crossBarFilter.Route(_audioOutPinIndex, _audioPinMap[analogChannel.AudioSource]); } _lastSignalUpdate = DateTime.MinValue; _tunerLocked = false; _previousChannel = analogChannel; Log.Log.WriteFile("HDPVR: Tuned to channel {0}", channel.Name); if (_graphState == GraphState.Idle) { _graphState = GraphState.Created; } _lastSignalUpdate = DateTime.MinValue; }
/// <summary> /// Stores a frequency override in the registry /// </summary> /// <param name="channel">Channel with frequency override</param> private static void SetFrequencyOverride(AnalogChannel channel) { int countryCode = channel.Country.Id; string[] registryLocations = new string[] { String.Format(@"Software\Microsoft\TV System Services\TVAutoTune\TS{0}-1", countryCode), String.Format(@"Software\Microsoft\TV System Services\TVAutoTune\TS{0}-0", countryCode), String.Format(@"Software\Microsoft\TV System Services\TVAutoTune\TS0-1"), String.Format(@"Software\Microsoft\TV System Services\TVAutoTune\TS0-0") }; if (channel.Frequency == 0) { //remove the frequency override in for (int index = 0; index < registryLocations.Length; index++) { using (RegistryKey registryKey = Registry.LocalMachine.CreateSubKey(registryLocations[index])) { if (registryKey != null) registryKey.DeleteValue(channel.ChannelNumber.ToString(), false); } using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(registryLocations[index])) { if (registryKey != null) registryKey.DeleteValue(channel.ChannelNumber.ToString(), false); } } return; } //set frequency override for (int index = 0; index < registryLocations.Length; index++) { using (RegistryKey registryKey = Registry.LocalMachine.CreateSubKey(registryLocations[index])) { if (registryKey != null) registryKey.SetValue(channel.ChannelNumber.ToString(), (int)channel.Frequency); } using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(registryLocations[index])) { if (registryKey != null) registryKey.SetValue(channel.ChannelNumber.ToString(), (int)channel.Frequency); } } }
/// <summary> /// Performs a tuning to the given channel /// </summary> /// <param name="analogChannel">The channel to tune to</param> public void PerformTune(AnalogChannel analogChannel) { if (_tuner == null || analogChannel == null) { throw new NullReferenceException(); } if (analogChannel.IsTv) { SetFrequencyOverride(analogChannel); } if (_currentChannel != null) { if (analogChannel.IsRadio != _currentChannel.IsRadio) { if (analogChannel.IsRadio) { Log.Log.WriteFile("analog: set to FM radio"); _tuner.put_Mode(AMTunerModeType.FMRadio); } else { Log.Log.WriteFile("analog: set to TV"); _tuner.put_Mode(AMTunerModeType.TV); } } if (analogChannel.Country.Id != _currentChannel.Country.Id) { _tuner.put_TuningSpace(analogChannel.Country.Id); _tuner.put_CountryCode(analogChannel.Country.Id); } if (analogChannel.TunerSource != _currentChannel.TunerSource) { _tuner.put_InputType(0, analogChannel.TunerSource); } if (analogChannel.IsRadio) { if (analogChannel.Frequency != _currentChannel.Frequency) { _tuner.put_Channel((int)analogChannel.Frequency, AMTunerSubChannel.Default, AMTunerSubChannel.Default); } } else { if (analogChannel.ChannelNumber != _currentChannel.ChannelNumber) { _tuner.put_Channel(analogChannel.ChannelNumber, AMTunerSubChannel.Default, AMTunerSubChannel.Default); } } } else { if (analogChannel.IsRadio) { Log.Log.WriteFile("analog: set to FM radio"); _tuner.put_Mode(AMTunerModeType.FMRadio); } else { Log.Log.WriteFile("analog: set to TV"); _tuner.put_Mode(AMTunerModeType.TV); } _tuner.put_TuningSpace(analogChannel.Country.Id); _tuner.put_CountryCode(analogChannel.Country.Id); _tuner.put_InputType(0, analogChannel.TunerSource); if (analogChannel.IsRadio) { _tuner.put_Channel((int)analogChannel.Frequency, AMTunerSubChannel.Default, AMTunerSubChannel.Default); } else { _tuner.put_Channel(analogChannel.ChannelNumber, AMTunerSubChannel.Default, AMTunerSubChannel.Default); } } _tuner.get_VideoFrequency(out _videoFrequency); _tuner.get_AudioFrequency(out _audioFrequency); _tunerLocked = false; _currentChannel = analogChannel; UpdateSignalQuality(); UpdateMinMaxChannel(); Log.Log.WriteFile("Analog: Tuned to country:{0} video:{1} Hz audio:{2} Hz locked:{3}", analogChannel.Country.Id, _videoFrequency, _audioFrequency, _tunerLocked); }
public static Dictionary <AnalogChannel, AnalogWaveProperties> MeasureAutoArrangeSettings(IScope scope, AnalogChannel aciveChannel, Action <float> progressReport) { float progress = 0f; progressReport(progress); //stop scope streaming scope.DataSourceScope.Stop(); //Prepare scope for test if (scope is SmartScope) { (scope as SmartScope).SetDisableVoltageConversion(false); } //set to timerange wide enough to capture 50Hz, but slightly off so smallest chance of aliasing const float initialTimeRange = 0.0277f; scope.AcquisitionMode = AcquisitionMode.AUTO; scope.AcquisitionLength = initialTimeRange; scope.SetViewPort(0, scope.AcquisitionLength); //s.AcquisitionDepth = 4096; scope.TriggerHoldOff = 0; scope.SendOverviewBuffer = false; AnalogTriggerValue atv = new AnalogTriggerValue(); atv.channel = AnalogChannel.ChA; atv.direction = TriggerDirection.RISING; atv.level = 5000; scope.TriggerAnalog = atv; foreach (AnalogChannel ch in AnalogChannel.List) { scope.SetCoupling(ch, Coupling.DC); } scope.CommitSettings(); progress += .1f; progressReport(progress); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // VERTICAL == VOLTAGE //set to largest input range float maxRange = 1.2f / 1f * 36f; foreach (AnalogChannel ch in AnalogChannel.List) { scope.SetVerticalRange(ch, -maxRange / 2f, maxRange / 2f); } float[] minValues = new float[] { float.MaxValue, float.MaxValue }; float[] maxValues = new float[] { float.MinValue, float.MinValue }; //measure min and max voltage over 3 full ranges for (int i = -1; i < 2; i++) { progress += .1f; progressReport(progress); foreach (AnalogChannel ch in AnalogChannel.List) { scope.SetYOffset(ch, (float)i * maxRange); } scope.CommitSettings(); System.Threading.Thread.Sleep(100); scope.ForceTrigger(); //fetch data DataPackageScope p = FetchLastFrame(scope); p = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!? if (p == null) { Logger.Error("Didn't receive data from scope, aborting"); return(null); } //check if min or max need to be updated (only in case this measurement was not saturated) float[] dataA = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array; float[] dataB = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array; float minA = dataA.Min(); float maxA = dataA.Max(); float minB = dataB.Min(); float maxB = dataB.Max(); if (minA != p.SaturationLowValue[AnalogChannel.ChA] && minA != p.SaturationHighValue[AnalogChannel.ChA] && minValues[0] > minA) { minValues[0] = minA; } if (minB != p.SaturationLowValue[AnalogChannel.ChB] && minB != p.SaturationHighValue[AnalogChannel.ChB] && minValues[1] > minB) { minValues[1] = minB; } if (maxA != p.SaturationLowValue[AnalogChannel.ChA] && maxA != p.SaturationHighValue[AnalogChannel.ChA] && maxValues[0] < maxA) { maxValues[0] = maxA; } if (maxB != p.SaturationLowValue[AnalogChannel.ChB] && maxB != p.SaturationHighValue[AnalogChannel.ChB] && maxValues[1] < maxB) { maxValues[1] = maxB; } } //calc ideal voltage range and offset float sizer = 3; //meaning 3 waves would fill entire view float[] coarseAmplitudes = new float[2]; coarseAmplitudes[0] = maxValues[0] - minValues[0]; coarseAmplitudes[1] = maxValues[1] - minValues[1]; float[] desiredOffsets = new float[2]; desiredOffsets[0] = (maxValues[0] + minValues[0]) / 2f; desiredOffsets[1] = (maxValues[1] + minValues[1]) / 2f; float[] desiredRanges = new float[2]; desiredRanges[0] = coarseAmplitudes[0] * sizer; desiredRanges[1] = coarseAmplitudes[1] * sizer; //intervene in case the offset is out of range for this range if (desiredRanges[0] < Math.Abs(desiredOffsets[0])) { desiredRanges[0] = Math.Abs(desiredOffsets[0]); } if (desiredRanges[1] < Math.Abs(desiredOffsets[1])) { desiredRanges[1] = Math.Abs(desiredOffsets[1]); } //set fine voltage range and offset scope.SetVerticalRange(AnalogChannel.ChA, -desiredRanges[0] / 2f, desiredRanges[0] / 2f); scope.SetYOffset(AnalogChannel.ChA, -desiredOffsets[0]); scope.SetVerticalRange(AnalogChannel.ChB, -desiredRanges[1] / 2f, desiredRanges[1] / 2f); scope.SetYOffset(AnalogChannel.ChB, -desiredOffsets[1]); scope.CommitSettings(); //now get data in order to find accurate lowHigh levels (as in coarse mode this was not accurate) DataPackageScope pFine = FetchLastFrame(scope); pFine = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!? Dictionary <AnalogChannel, float[]> dataFine = new Dictionary <AnalogChannel, float[]>(); dataFine.Add(AnalogChannel.ChA, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array); dataFine.Add(AnalogChannel.ChB, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array); Dictionary <AnalogChannel, float> minimumValues = new Dictionary <AnalogChannel, float>(); Dictionary <AnalogChannel, float> maximumValues = new Dictionary <AnalogChannel, float>(); Dictionary <AnalogChannel, float> amplitudes = new Dictionary <AnalogChannel, float>(); Dictionary <AnalogChannel, float> offsets = new Dictionary <AnalogChannel, float>(); Dictionary <AnalogChannel, bool> isFlatline = new Dictionary <AnalogChannel, bool>(); foreach (var kvp in dataFine) { minimumValues.Add(kvp.Key, kvp.Value.Min()); maximumValues.Add(kvp.Key, kvp.Value.Max()); amplitudes.Add(kvp.Key, kvp.Value.Max() - kvp.Value.Min()); offsets.Add(kvp.Key, (kvp.Value.Max() + kvp.Value.Min()) / 2f); isFlatline.Add(kvp.Key, amplitudes[kvp.Key] < 0.01f); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HORIZONTAL == FREQUENCY const float minTimeRange = 500f * 0.00000001f;//500 samples over full hor span const float maxTimeRange = 1f; double frequency, frequencyError, dutyCycle, dutyCycleError; Dictionary <AnalogChannel, double> finalFrequencies = new Dictionary <AnalogChannel, double>(); finalFrequencies.Add(AnalogChannel.ChA, double.MaxValue); finalFrequencies.Add(AnalogChannel.ChB, double.MaxValue); int iterationCounter = 0; //only for performance testing float currTimeRange = minTimeRange; bool continueLooping = true; if (isFlatline.Where(x => x.Value).ToList().Count == isFlatline.Count) //no need to find frequency in case of 2 DC signals { continueLooping = false; } while (continueLooping) { progress += .04f; progressReport(progress); iterationCounter++; //only for performance testing scope.AcquisitionLength = currTimeRange; scope.SetViewPort(0, scope.AcquisitionLength); scope.CommitSettings(); DataPackageScope pHor = FetchLastFrame(scope); pHor = FetchLastFrame(scope); Dictionary <AnalogChannel, float[]> timeData = new Dictionary <AnalogChannel, float[]>(); timeData.Add(AnalogChannel.ChA, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array); timeData.Add(AnalogChannel.ChB, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array); foreach (var kvp in timeData) { //make sure entire amplitude is in view float currMinVal = kvp.Value.Min(); float currMaxVal = kvp.Value.Max(); float lowMarginValue = minimumValues[kvp.Key] + amplitudes[kvp.Key] * 0.1f; float highMarginValue = maximumValues[kvp.Key] - amplitudes[kvp.Key] * 0.1f; if (currMinVal > lowMarginValue) { break; } if (currMaxVal < highMarginValue) { break; } ComputeFrequencyDutyCycle(pHor.GetData(DataSourceType.Viewport, kvp.Key), out frequency, out frequencyError, out dutyCycle, out dutyCycleError); if (!double.IsNaN(frequency) && (finalFrequencies[kvp.Key] == double.MaxValue)) { finalFrequencies[kvp.Key] = frequency; } } //update and check whether we've found what we were looking for currTimeRange *= 100f; bool freqFoundForAllActiveWaves = true; foreach (var kvp in timeData) { if (!isFlatline[kvp.Key] && finalFrequencies[kvp.Key] == double.MaxValue) { freqFoundForAllActiveWaves = false; } } continueLooping = !freqFoundForAllActiveWaves; if (currTimeRange > maxTimeRange) { continueLooping = false; } } //in case of flatline or very low freq, initial value will not have changed foreach (AnalogChannel ch in finalFrequencies.Keys.ToList()) { if (finalFrequencies[ch] == double.MaxValue) { finalFrequencies[ch] = 0; } } Dictionary <AnalogChannel, AnalogWaveProperties> waveProperties = new Dictionary <AnalogChannel, AnalogWaveProperties>(); foreach (var kvp in isFlatline) { waveProperties.Add(kvp.Key, new AnalogWaveProperties(minimumValues[kvp.Key], maximumValues[kvp.Key], amplitudes[kvp.Key], offsets[kvp.Key], isFlatline[kvp.Key], finalFrequencies[kvp.Key])); } return(waveProperties); }
private Schema WriteSchemaFile(COMTRADEData comtradeData, string schemaFilePath) { Schema schema = Writer.CreateSchema(new List <ChannelMetadata>(), comtradeData.StationName, comtradeData.DeviceID, comtradeData.DataStartTime, comtradeData.SampleCount, samplingRate: comtradeData.SamplingRate, includeFracSecDefinition: false, nominalFrequency: m_systemFrequency); List <AnalogChannel> analogChannels = new List <AnalogChannel>(); List <DigitalChannel> digitalChannels = new List <DigitalChannel>(); int i = 1; // Populate the analog channel list with analog channel metadata foreach (COMTRADEChannelData channelData in comtradeData.AnalogChannelData) { AnalogChannel analogChannel = new AnalogChannel(); analogChannel.Index = i; analogChannel.Name = channelData.Name; analogChannel.MinValue = -short.MaxValue; analogChannel.MaxValue = short.MaxValue; analogChannel.Units = channelData.Units; if ((object)channelData.OriginalAnalogChannel != null) { analogChannel.PhaseID = channelData.OriginalAnalogChannel.PhaseID; analogChannel.CircuitComponent = channelData.OriginalAnalogChannel.CircuitComponent; analogChannel.Units = channelData.OriginalAnalogChannel.Units; analogChannel.Skew = channelData.OriginalAnalogChannel.Skew; analogChannel.PrimaryRatio = channelData.OriginalAnalogChannel.PrimaryRatio; analogChannel.SecondaryRatio = channelData.OriginalAnalogChannel.SecondaryRatio; analogChannel.ScalingIdentifier = channelData.OriginalAnalogChannel.ScalingIdentifier; if (analogChannel.Units.ToUpper().Contains("KA") || analogChannel.Units.ToUpper().Contains("KV")) { channelData.Data = channelData.Data.Multiply(0.001); } } analogChannel.Multiplier = (channelData.Data.Maximum - channelData.Data.Minimum) / (2 * short.MaxValue); analogChannel.Adder = (channelData.Data.Maximum + channelData.Data.Minimum) / 2.0D; analogChannels.Add(analogChannel); i++; } i = 1; // Populate the digital channel list with digital channel metadata foreach (COMTRADEChannelData channelData in comtradeData.DigitalChannelData) { DigitalChannel digitalChannel = new DigitalChannel(); digitalChannel.Index = i; digitalChannel.Name = channelData.Name; if ((object)channelData.OriginalDigitalChannel != null) { digitalChannel.PhaseID = channelData.OriginalDigitalChannel.PhaseID; digitalChannel.CircuitComponent = channelData.OriginalDigitalChannel.CircuitComponent; digitalChannel.NormalState = channelData.OriginalDigitalChannel.NormalState; } digitalChannels.Add(digitalChannel); i++; } schema.AnalogChannels = analogChannels.ToArray(); schema.DigitalChannels = digitalChannels.ToArray(); // Dump the generated schema to the schema file File.WriteAllText(FilePath.GetAbsolutePath(schemaFilePath), schema.FileImage, Encoding.ASCII); // Return the schema return(schema); }
/// <summary> /// Отрисовка контрола /// </summary> /// <returns>Текущее изображение</returns> private RenderTargetBitmap Render() { DrawingVisual drawingVisual = new DrawingVisual(); var border = 20; var radius = (int)((Math.Min(_size.Width, _size.Height) - border) / 2); var mid = radius + border / 2; using (DrawingContext drawingContext = drawingVisual.RenderOpen()) { //Заливка цветом drawingContext.DrawRectangle(Brushes.White, null, new Rect(0, 0, _size.Width, _size.Height)); Pen pen; for (int i = 0; i < CIRCLE_COUNT; i++) { pen = i == 0 ? BlackPen : DashBlackPen; var currentRadius = radius / (double)CIRCLE_COUNT * (CIRCLE_COUNT - i); drawingContext.DrawEllipse(null, pen, new Point(mid, mid), currentRadius, currentRadius); } for (int i = 0; i < 360; i += 30) { pen = (i % 90) == 0 ? BlackPen : DashBlackPen; var х1 = mid + (Math.Cos(i * Math.PI / 180.0) * radius); var у1 = mid - (Math.Sin(i * Math.PI / 180.0) * radius); drawingContext.DrawLine(pen, new Point(mid, mid), new Point(х1, у1)); } var formattedText = new FormattedText( "180", CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 12, Brushes.Black); drawingContext.DrawText(formattedText, new Point(border / 2.0, mid)); formattedText = new FormattedText( "0", CultureInfo.GetCultureInfo("en-us"), FlowDirection.RightToLeft, new Typeface("Verdana"), 12, Brushes.Black); drawingContext.DrawText(formattedText, new Point(border / 2.0 + radius * 2, mid)); formattedText = new FormattedText( "90", CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 12, Brushes.Black); drawingContext.DrawText(formattedText, new Point(mid, border / 2.0)); formattedText = new FormattedText( "270", CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 12, Brushes.Black); drawingContext.DrawText(formattedText, new Point(mid, border / 2.0 + radius * 2 - formattedText.Height)); if (Channels != null) { var baseChannel = this.Channels.FirstOrDefault(o => o.Name == _startingPoint); var baseAngle = 0.0; if (baseChannel != null) { baseAngle = GetAngle(baseChannel.FirstHarmonic[_index]); } var enabledVectors = this.Channels.Where(o => o.Options.Vector).ToArray(); this._infos = new VectorChannelInfo[enabledVectors.Length]; double maxValueI = enabledVectors.Where(o => o.ThisType == AnalogChannel.ChannelType.I).Select(channel => channel.FirstHarmonicDouble[_index]).Concat(new[] { 0.0 }).Max(); double maxValueU = enabledVectors.Where(o => o.ThisType == AnalogChannel.ChannelType.U).Select(channel => channel.FirstHarmonicDouble[_index]).Concat(new[] { 0.0 }).Max(); double maxValueUnknown = enabledVectors.Where(o => o.ThisType == AnalogChannel.ChannelType.UNKNOWN).Select(channel => channel.FirstHarmonicDouble[_index]).Concat(new[] { 0.0 }).Max(); for (int i = 0; i < enabledVectors.Length; i++) { var max = 0.0; Pen currentPen; switch (enabledVectors[i].ThisType) { case AnalogChannel.ChannelType.I: { max = maxValueI; currentPen = PensI[enabledVectors[i].ChannelBrush]; break; } case AnalogChannel.ChannelType.U: { max = maxValueU; currentPen = PensU[enabledVectors[i].ChannelBrush]; break; } default: { max = maxValueUnknown; currentPen = BlackPen; break; } } double factor = enabledVectors[i].FirstHarmonicDouble[_index] / max; Point point = enabledVectors[i].FirstHarmonic[_index]; double a = this.GetAngle(point) - baseAngle; if (a < 0) { a += 360; } double x1 = mid + (Math.Cos(-a * Math.PI / 180.0) * radius) * factor; double y1 = mid + (Math.Sin(-a * Math.PI / 180.0) * radius) * factor; drawingContext.DrawLine(currentPen, new Point(mid, mid), new Point(x1, y1)); this._infos[i] = new VectorChannelInfo(enabledVectors[i].Name, currentPen.Brush, AnalogChannel.Normalize(enabledVectors[i].FirstHarmonicDouble[_index], enabledVectors[i].Measure), Math.Round(a).ToString(CultureInfo.InvariantCulture)); if (Math.Sqrt(Math.Pow(x1 - mid, 2) + Math.Pow(y1 - mid, 2)) < 10) { continue; } PathGeometry sad = new PathGeometry(new[] { new PathFigure(this.Rotate(new Point(0, 0), a, new Point(x1, y1)), new[] { new LineSegment(this.Rotate(new Point(-10, 3), -a, new Point(x1, y1)), false), new LineSegment(this.Rotate(new Point(-10, -3), -a, new Point(x1, y1)), false) } , true) }); drawingContext.DrawGeometry(currentPen.Brush, currentPen, sad); } } } RenderTargetBitmap bmp = new RenderTargetBitmap(radius * 2 + border, radius * 2 + border, 0, 0, PixelFormats.Pbgra32); bmp.Render(drawingVisual); bmp.Freeze(); return(bmp); }
private void ExportToCOMTRADE(string filePath, ControlFile controlFile, string identityString, List <ANLG_CHNL_NEW> analogChannels, List <EVNT_CHNL_NEW> digitalChannels) { string assetKey = GetMeterKey(filePath, m_filePattern) ?? ThreadContext.Properties["Meter"].ToString(); string rootFileName = FilePath.GetFileNameWithoutExtension(filePath); string directoryPath = Path.Combine(m_emaxSettings.COMTRADEExportDirectory, assetKey); string schemaFilePath = Path.Combine(directoryPath, $"{rootFileName}.cfg"); string dataFilePath = Path.Combine(directoryPath, $"{rootFileName}.dat"); Schema comtradeSchema = new Schema(); if (File.Exists(dataFilePath)) { return; } comtradeSchema.StationName = Regex.Replace(identityString, @"[\r\n]", ""); comtradeSchema.Version = 2013; comtradeSchema.AnalogChannels = new AnalogChannel[controlFile.AnalogChannelCount]; comtradeSchema.DigitalChannels = new DigitalChannel[controlFile.EventChannelSettings.Count]; comtradeSchema.SampleRates = new SampleRate[1]; comtradeSchema.SampleRates[0].Rate = controlFile.SystemParameters.samples_per_second; comtradeSchema.SampleRates[0].EndSample = controlFile.SystemParameters.rcd_sample_count - 1; comtradeSchema.StartTime = new Timestamp() { Value = m_meterDataSet.DataSeries[1][0].Time }; int triggerIndex = controlFile.SystemParameters.start_offset_samples + controlFile.SystemParameters.prefault_samples; comtradeSchema.TriggerTime = new Timestamp() { Value = m_meterDataSet.DataSeries[1][triggerIndex].Time }; for (int i = 0; i < analogChannels.Count; i++) { ANLG_CHNL_NEW analogChannel = analogChannels[i]; AnalogChannel comtradeAnalog = new AnalogChannel(); DataSeries channelData = m_meterDataSet.DataSeries[i + 1]; double unitMultiplier = 1.0D; double max = channelData.Maximum; double min = channelData.Minimum; double num; comtradeAnalog.Index = i + 1; comtradeAnalog.Name = analogChannel.title; comtradeAnalog.Units = new Func <string, string>(type => { switch (type) { case "V": return("kVAC"); case "A": return("kAAC"); case "v": return(" VDC"); default: return(type); } })(analogChannel.type); if (analogChannel.type.All(char.IsUpper)) { unitMultiplier = 0.001D; max *= unitMultiplier; min *= unitMultiplier; } comtradeAnalog.Multiplier = (max - min) / (2 * short.MaxValue); comtradeAnalog.Adder = (max + min) / 2.0D; comtradeAnalog.PrimaryRatio = double.TryParse(analogChannel.primary, out num) ? num * unitMultiplier : 0.0D; comtradeAnalog.SecondaryRatio = double.TryParse(analogChannel.secondary, out num) ? num * unitMultiplier : 0.0D; comtradeSchema.AnalogChannels[i] = comtradeAnalog; } for (int i = 0; i < digitalChannels.Count; i++) { EVNT_CHNL_NEW digitalChannel = digitalChannels[i]; DigitalChannel comtradeDigital = new DigitalChannel(); comtradeDigital.Index = i + 1; comtradeDigital.ChannelName = digitalChannel.e_title; comtradeSchema.DigitalChannels[i] = comtradeDigital; } Directory.CreateDirectory(directoryPath); File.WriteAllText(schemaFilePath, comtradeSchema.FileImage, Encoding.ASCII); using (FileStream stream = File.OpenWrite(dataFilePath)) { const int DigitalSize = sizeof(ushort) * 8; IEnumerable <DataSeries> digitalWords = m_meterDataSet.Digitals.Skip(1) .Select((dataSeries, index) => dataSeries.Multiply(Math.Pow(2.0D, DigitalSize - (index % DigitalSize) - 1))) .Select((DataSeries, Index) => new { DataSeries, Index }) .GroupBy(obj => obj.Index / DigitalSize) .Select(grouping => grouping.Select(obj => obj.DataSeries)) .Select(grouping => grouping.Aggregate((sum, series) => sum.Add(series))); List <DataSeries> allChannels = m_meterDataSet.DataSeries.Skip(1) .Select((dataSeries, index) => analogChannels[index].type.All(char.IsUpper) ? dataSeries.Multiply(0.001D) : dataSeries) .Concat(digitalWords) .ToList(); for (int i = 0; i < m_meterDataSet.DataSeries[1].DataPoints.Count; i++) { DateTime timestamp = m_meterDataSet.DataSeries[1][i].Time; double[] values = allChannels .Select(dataSeries => dataSeries[i].Value) .ToArray(); Writer.WriteNextRecordBinary(stream, comtradeSchema, timestamp, values, (uint)i, false); } } }
public static IAnalogInput Get(AnalogChannel channel) { return((IAnalogInput)Cache.GetIfActive(channel)); }