Example #1
0
 /// <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;
 }
Example #2
0
    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;
    }
Example #3
0
 /// <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);
     }
   }
 }
Example #4
0
 /// <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);
 }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
        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);
                }
            }
        }
Example #9
0
 public static IAnalogInput Get(AnalogChannel channel)
 {
     return((IAnalogInput)Cache.GetIfActive(channel));
 }