3

Playback Enable Function

I'm adding a button called "Playback", and it's function needs to take Start and End Date/Time Pickers, calculate span, update screen properties, and set playback properties automatically.  I know how to script most of that, but I want to be able to Enable the PlaybackMode in the script.  I just can't find any documentation on the Playback functionality.  

I can see that certain properties like PlaybackStart, PlaybackDuration, PlaybackSpeed, PlaybackMode, and even PlaybackPosition exist, but I need to know how to set PlaybackMode to "Enabled" and push DateTime and span values into the properties using script initiated with a Button.  

Does anyone know how to do this?  I can't find it in any of the documentation.

4 replies

null
    • smason
    • 11 mths ago
    • Reported - view

    Hi ryan ,

    I asked our development team about this. Unfortunately, the Playback properties were not meant to be posted publicly as they were only for internal use. We never intended users to interact with the Playback functionality through scripting as it is a little weird/complex getting Apps/Trends to work together. Sorry I don't have a better answer for you.

      • ryan
      • 11 mths ago
      • Reported - view

      Steve , but...I wanna do it...the functionality of what I'm trying to do would be very useful and applied to many of our screens.  I really just need to know how to 'enable'/'disable' the playback bar in the script (have it appear/disappear) and update a few properties to use (similar to that URL solution for reporting).  How can we make this happen?  I don't want to know everything but...just as my kid says....a lil bit.  The playback functionality is pretty darned useful.

    • laruer
    • 11 mths ago
    • Reported - view

    Hi ryan ,

    You can control playback with scripting and you can even loop the playback if you like. Getting references to the playback properties requires using reflection. And once you do that, you do have to create your own EventTimer to periodically update the playback position.

    Some interesting applications could be setting up an EventsTable to set the playback parameters to the start and end time of an event when an event from the table is clicked.

    Below is a example application and the script to create it.

    using AxiomCore2.Client;
    using AxiomCore2.ControlProperties;
    using AxiomCore2.Controls;
    using AxiomCore2.Data;
    using AxiomCore2.Events;
    using AxiomCore2.Legacy;
    using AxiomCore2.Log;
    using AxiomCore2.Managers;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Collections;
    using System.Drawing;
    //using CanaryWebServiceHelper;
    //using CanaryWebServiceHelper.HistorianWebService;
    
    namespace AxiomScript
    {
        public partial class ScreenScript : IDisposable
        {
            // NOTE: click help icon in dialog header for API documentation and examples.
            // NOTE: use EventTimer class when timer is necessary. See API documentation.
    
            // axiom references
            public ControlApplication Application { get; } = ControlApplication.Instance;
            public ControlFactoryManager ControlFactory { get; } = ControlFactoryManager.Instance;
            public IDataProvider DataProvider { get; } = DataProviderManager.CreateInstance();
            public ILog Log { get; } = ClientLog.UserScript;
            public NavigationManager Navigation { get; } = NavigationManager.Instance;
            public ControlScreen Screen => _screen;
    
            System.Reflection.PropertyInfo playbackModeProperty;
            System.Reflection.PropertyInfo playbackPositionProperty;
            System.Reflection.PropertyInfo playbackDurationProperty;
            System.Reflection.PropertyInfo playbackSpeedProperty;
            System.Reflection.PropertyInfo playbackStartProperty;
    
            bool loopPlayback;
    
            private EventTimer playbackTimer = null;
            private int playbackTimerInitialTime = 0;
            private int playbackTimerInterval = 250;
    
            public void OnScreenVisible()
            {
                //Get references to the playback properties using reflection
                playbackModeProperty = Application.GetType().GetProperty("AxiomCore2.IComponentPlayback.PlaybackMode",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                playbackPositionProperty = Application.GetType().GetProperty("AxiomCore2.IComponentPlayback.PlaybackPosition",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                playbackDurationProperty = Application.GetType().GetProperty("AxiomCore2.IComponentPlayback.PlaybackDuration",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                playbackSpeedProperty = Application.GetType().GetProperty("AxiomCore2.IComponentPlayback.PlaybackSpeed",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                playbackStartProperty = Application.GetType().GetProperty("AxiomCore2.IComponentPlayback.PlaybackStart",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    
                #region Controls
                //Set up example playback controls
                if(!Screen.ScreenControls.ContainsKey("SetStartButton")){
                    var setStartButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "SetStartButton");
                    Screen.Children.Add(setStartButton);
                    setStartButton.Text = "Set Start";
                    setStartButton.Width = 175;
                    setStartButton.X = 0;
                    setStartButton.Y = 0;
                    setStartButton.OnClick = "SetStartButton_OnClick";
                }
    
                //Start Time
                ControlDateTimePicker playbackStartDateTimePicker;
                if(!Screen.ScreenControls.ContainsKey("PlaybackStartDateTimePicker")){
                    playbackStartDateTimePicker = (ControlDateTimePicker)ControlFactory.CreateControl(ControlKind.DateTimePicker, "PlaybackStartDateTimePicker");
                    Screen.Children.Add(playbackStartDateTimePicker);
                    playbackStartDateTimePicker.X = 0;
                    playbackStartDateTimePicker.Y = 50;
                    playbackStartDateTimePicker.DateTime = (DateTime)playbackStartProperty.GetValue(Application);
                } else {
                    playbackStartDateTimePicker = Screen.ScreenControls["PlaybackStartDateTimePicker"] as ControlDateTimePicker;
                    playbackStartDateTimePicker.DateTime = (DateTime)playbackStartProperty.GetValue(Application);
                }
                playbackStartDateTimePicker.DateTime = (DateTime)playbackStartProperty.GetValue(Application);
    
                if(!Screen.ScreenControls.ContainsKey("SetPositionButton")){
                    var setPositionButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "SetPositionButton");
                    Screen.Children.Add(setPositionButton);
                    setPositionButton.Text = "Set Position";
                    setPositionButton.Width = 175;
                    setPositionButton.X = 250;
                    setPositionButton.Y = 0;
                    setPositionButton.OnClick = "SetPositionButton_OnClick";
                }
    
                //Position
                ControlDateTimePicker playbackPositionDateTimePicker;
                if(!Screen.ScreenControls.ContainsKey("PlaybackPositionDateTimePicker")){
                    playbackPositionDateTimePicker = (ControlDateTimePicker)ControlFactory.CreateControl(ControlKind.DateTimePicker, "PlaybackPositionDateTimePicker");
                    Screen.Children.Add(playbackPositionDateTimePicker);
                    playbackPositionDateTimePicker.X = 250;
                    playbackPositionDateTimePicker.Y = 50;
                } else {
                    playbackPositionDateTimePicker = Screen.ScreenControls["PlaybackPositionDateTimePicker"] as ControlDateTimePicker;
                }
                playbackPositionDateTimePicker.DateTime = (DateTime)playbackPositionProperty.GetValue(Application);
    
                if(!Screen.ScreenControls.ContainsKey("SetDurationButton")){
                    var setDurationButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "SetDurationButton");
                    Screen.Children.Add(setDurationButton);
                    setDurationButton.Text = "Set Duration";
                    setDurationButton.Width = 175;
                    setDurationButton.X = 500;
                    setDurationButton.Y = 0;
                    setDurationButton.OnClick = "SetDurationButton_OnClick";
                }
                if(!Screen.ScreenControls.ContainsKey("DurationTextBox")){
                    var durationTextBox = (ControlTextBox)ControlFactory.CreateControl(ControlKind.TextBox, "DurationTextBox");
                    Screen.Children.Add(durationTextBox);
                    durationTextBox.X = 500;
                    durationTextBox.Y = 50;
                    durationTextBox.Text = playbackDurationProperty.GetValue(Application).ToString();
                }
                if(!Screen.ScreenControls.ContainsKey("SetSpeedButton")){
                    var setSpeedButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "SetSpeedButton");
                    Screen.Children.Add(setSpeedButton);
                    setSpeedButton.Text = "Set Speed";
                    setSpeedButton.Width = 175;
                    setSpeedButton.X = 750;
                    setSpeedButton.Y = 0;
                    setSpeedButton.OnClick = "SetSpeedButton_OnClick";
                }
    
                //Speed
                ControlTextBox speedTextBox;
                if(!Screen.ScreenControls.ContainsKey("SpeedTextBox")){
                    speedTextBox = (ControlTextBox)ControlFactory.CreateControl(ControlKind.TextBox, "SpeedTextBox");
                    Screen.Children.Add(speedTextBox);
                    speedTextBox.X = 750;
                    speedTextBox.Y = 50;
    
                } else {
                    speedTextBox = Screen.ScreenControls["SpeedTextBox"] as ControlTextBox;
                }
                speedTextBox.Text = playbackSpeedProperty.GetValue(Application).ToString();
    
                if(!Screen.ScreenControls.ContainsKey("EnablePlaybackButton")){
                    var enablePlaybackButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "EnablePlaybackButton");
                    Screen.Children.Add(enablePlaybackButton);
                    enablePlaybackButton.Text = "Enable Playback";
                    enablePlaybackButton.Width = 175;
                    enablePlaybackButton.X = 0;
                    enablePlaybackButton.Y = 100;
                    enablePlaybackButton.OnClick = "EnablePlaybackButton_OnClick";
                }
    
                if(!Screen.ScreenControls.ContainsKey("DisablePlaybackButton")){
                    var disablePlaybackButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "DisablePlaybackButton");
                    Screen.Children.Add(disablePlaybackButton);
                    disablePlaybackButton.Text = "Disable Playback";
                    disablePlaybackButton.Width = 175;
                    disablePlaybackButton.X = 200;
                    disablePlaybackButton.Y = 100;
                    disablePlaybackButton.OnClick = "DisablePlaybackButton_OnClick";
                }
    
                if(!Screen.ScreenControls.ContainsKey("StartPlaybackButton")){
                    var startPlaybackButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "StartPlaybackButton");
                    Screen.Children.Add(startPlaybackButton);
                    startPlaybackButton.Text = "Start Playback";
                    startPlaybackButton.Width = 175;
                    startPlaybackButton.X = 0;
                    startPlaybackButton.Y = 150;
                    startPlaybackButton.OnClick = "StartPlaybackButton_OnClick";
                }
    
                if(!Screen.ScreenControls.ContainsKey("StopPlaybackButton")){
                    var stopPlaybackButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "StopPlaybackButton");
                    Screen.Children.Add(stopPlaybackButton);
                    stopPlaybackButton.Text = "Stop Playback";
                    stopPlaybackButton.Width = 175;
                    stopPlaybackButton.X = 200;
                    stopPlaybackButton.Y = 150;
                    stopPlaybackButton.OnClick = "StopPlaybackButton_OnClick";
                }
    
                if(!Screen.ScreenControls.ContainsKey("LoopPlaybackListBox")){
                    var loopPlaybackListBox = (ControlListBox)ControlFactory.CreateControl(ControlKind.ListBox, "LoopPlaybackListBox");
                    Screen.Children.Add(loopPlaybackListBox);
                    loopPlaybackListBox.Items = new string[]{"Loop"};
                    loopPlaybackListBox.Width = 175;
                    loopPlaybackListBox.Height = 50;
                    loopPlaybackListBox.X = 400;
                    loopPlaybackListBox.Y = 150;
                    loopPlaybackListBox.OnSelectionChange = "LoopPlaybackListBox_OnSelectionChange";
                } else {
                    var loopPlaybackListBox = Screen.ScreenControls["LoopPlaybackListBox"] as ControlListBox;
                    loopPlaybackListBox.SelectedItems = new string[]{};
                }
    
                if(!Screen.ScreenControls.ContainsKey("GetInfoButton")){
                    var getInfoButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "GetInfoButton");
                    Screen.Children.Add(getInfoButton);
                    getInfoButton.Text = "Get Info";
                    getInfoButton.X = 400;
                    getInfoButton.Y = 100;
                    getInfoButton.OnClick = "GetInfoButton_OnClick";
                }
    
                if(!Screen.ScreenControls.ContainsKey("SetTimerMsButton")){
                    var setTimerMsButton = (ControlButton)ControlFactory.CreateControl(ControlKind.Button, "SetTimerMsButton");
                    Screen.Children.Add(setTimerMsButton);
                    setTimerMsButton.Text = "Set Timer ms";
                    setTimerMsButton.Width = 175;
                    setTimerMsButton.X = 600;
                    setTimerMsButton.Y = 100;
                    setTimerMsButton.OnClick = "SetTimerMsButton_OnClick";
                }
    
                //Timer Milliseconds - Defaults to 250 milliseconds.
                //Set to a higher number to refresh less often which is good for low bandwidth connections
                ControlTextBox timerMsTextBox;
                if(!Screen.ScreenControls.ContainsKey("TimerMsTextBox")){
                    timerMsTextBox = (ControlTextBox)ControlFactory.CreateControl(ControlKind.TextBox, "TimerMsTextBox");
                    Screen.Children.Add(timerMsTextBox);
                    timerMsTextBox.X = 600;
                    timerMsTextBox.Y = 150;
                } else {
                    timerMsTextBox = Screen.ScreenControls["TimerMsTextBox"] as ControlTextBox;
                }
                timerMsTextBox.Text = playbackTimerInterval.ToString();
    
                if(!Screen.ScreenControls.ContainsKey("CPUSparkChart")){
                    var cpuSparkChart = (ControlSparkChart)ControlFactory.CreateControl(ControlKind.SparkChart, "CPUSparkChart");
                    Screen.Children.Add(cpuSparkChart);
                    cpuSparkChart.X = 0;
                    cpuSparkChart.Y = 300;
                    cpuSparkChart.Width = 1024;
                    cpuSparkChart.Height = 200;
                    cpuSparkChart.SourceTag = "localhost.{Diagnostics}.Sys.CPU Usage Total";
                }
                #endregion Controls
            }
    
            public void OnScreenInvisible()
            {
            }
    
            public void Dispose()
            {
            }
    
            //This gets called every time the playbackTimer ticks (defaults to every 250 ms)
            //This updates the playback position to a new position or stop playback if it reaches the end
            private void PlaybackTimerCallback(EventTimer timer, object userData)
            {
                var position = (DateTime)playbackPositionProperty.GetValue(Application);
                var speed = (TimeSpan)playbackSpeedProperty.GetValue(Application);
                var duration = (TimeSpan)playbackDurationProperty.GetValue(Application);
                var start = (DateTime)playbackStartProperty.GetValue(Application);
                var end = start + duration;
                double speedRatio = ((double)playbackTimerInterval / (double)1000.0);
                var increment = TimeSpan.FromMilliseconds(speedRatio * speed.TotalMilliseconds);
                //Uncomment the line below to show debugging info
                //Log.Info($"Speed: {speed} Ratio: {speedRatio} Inc: {increment} Pos: {position} NewPos: {position + increment} End: {end}");
                if((position + increment) <= end)
                {
                    playbackPositionProperty.SetValue(Application, position + increment);
                }
                else if(loopPlayback == true)
                {
                    //Log.Info("Looping playback");
                    playbackPositionProperty.SetValue(Application, start);
                }
                else
                {
                    //Playback has reached the end
                    StopPlayback();
                }
            }
    
            public void GetInfoButton_OnClick(object sender, EventArgs eventArgs)
            {
                GetPlaybackInfo();
            }
    
            //Print the playback parameters to the log
            public void GetPlaybackInfo()
            {
                Log.Info($"Mode = {playbackModeProperty.GetValue(Application)}, Start = {playbackStartProperty.GetValue(Application)}, Position = {playbackPositionProperty.GetValue(Application)}, Duration = {playbackDurationProperty.GetValue(Application)}, Speed = {playbackSpeedProperty.GetValue(Application)}");
            }
    
    
            public void SetTimerMsButton_OnClick(object sender, EventArgs eventArgs)
            {
                int interval;
                var timerMsTextBox = Screen.ScreenControls["TimerMsTextBox"] as ControlTextBox;
                if(int.TryParse(timerMsTextBox.Text, out interval)){
                    playbackTimerInterval = interval;
                } else {
                    Log.Info($"Could not parse timer milliseconds {timerMsTextBox.Text}");
                }
            }
    
            public void SetStartButton_OnClick(object sender, EventArgs eventArgs)
            {
                var playbackStartDateTimePicker = Screen.ScreenControls["PlaybackStartDateTimePicker"] as ControlDateTimePicker;
                playbackStartProperty.SetValue(Application, playbackStartDateTimePicker.DateTime);
            }
    
            public void SetPositionButton_OnClick(object sender, EventArgs eventArgs)
            {
                var playbackPositionDateTimePicker = Screen.ScreenControls["PlaybackPositionDateTimePicker"] as ControlDateTimePicker;
                playbackPositionProperty.SetValue(Application, playbackPositionDateTimePicker.DateTime);
            }
    
            public void SetDurationButton_OnClick(object sender, EventArgs eventArgs)
            {
                var durationTextBox = Screen.ScreenControls["DurationTextBox"] as ControlTextBox;
                TimeSpan duration;
                if(TimeSpan.TryParse(durationTextBox.Text, out duration)){
                    playbackDurationProperty.SetValue(Application, duration);
                } else {
                    Log.Info($"Could not parse duration {durationTextBox.Text}");
                }
            }
    
            public void SetSpeedButton_OnClick(object sender, EventArgs eventArgs)
            {
                var speedTextBox = Screen.ScreenControls["SpeedTextBox"] as ControlTextBox;
                TimeSpan speed;
                if(TimeSpan.TryParse(speedTextBox.Text, out speed)){
                    playbackSpeedProperty.SetValue(Application, speed);
                } else {
                    Log.Info($"Could not parse speed {speedTextBox.Text}");
                }
            }
    
            public void EnablePlaybackButton_OnClick(object sender, EventArgs eventArgs)
            {
                playbackModeProperty.SetValue(Application, 0);
            }
    
            public void DisablePlaybackButton_OnClick(object sender, EventArgs eventArgs)
            {
                playbackModeProperty.SetValue(Application, 1);
            }
    
            public void StartPlaybackButton_OnClick(object sender, EventArgs eventArgs)
            {
                StartPlayback();
            }
    
            public void StartPlayback()
            {
                if (playbackTimer == null)
                {
                    // initialize timer
                    playbackTimer = new EventTimer(
                        callback: PlaybackTimerCallback,
                        dueTime: playbackTimerInitialTime,
                        period: playbackTimerInterval);
                }
                else
                {
                    // reset timer
                    playbackTimer.Change(
                        dueTime: playbackTimerInitialTime,
                        period: playbackTimerInterval);
                }
            }
    
            public void StopPlaybackButton_OnClick(object sender, EventArgs eventArgs)
            {
                StopPlayback();
            }
    
            public void StopPlayback()
            {
                if (playbackTimer != null)
                {
                    // pause timer
                    playbackTimer.Change(
                        dueTime: EventTimer.Infinite,
                        period: EventTimer.Infinite);
                }
            }
    
            public void LoopPlaybackListBox_OnSelectionChange(object sender, string[] selectedItems)
            {
                var selectedItem = selectedItems.FirstOrDefault();
                loopPlayback = selectedItem == "Loop";
            }
        }
    }
    
      • ryan
      • 11 mths ago
      • Reported - view

      laruer not all heroes wear capes.  You sir, are a hero.

Content aside

print this pagePrint this page
  • 3 Likes
  • 11 mths agoLast active
  • 4Replies
  • 113Views
  • 4 Following