aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/TechItems/ProcessParametersItem.cs
blob: 4aedf8bc7ff529abb686889d23ade2dacbb0a818 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Xml.Serialization;
using Tango.BL;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.SharedUI.Helpers;

namespace Tango.MachineStudio.Technician.TechItems
{
    /// <summary>
    /// Represents a process parameters table item.
    /// </summary>
    /// <seealso cref="Tango.MachineStudio.Technician.TechItems.TechItem" />
    [TechItem(20)]
    public class ProcessParametersItem : TechItem
    {
        public static ObservableCollection<ProcessParametersTable> ProcessParametersTables { get; set; }

        static ProcessParametersItem()
        {
            ProcessParametersTables = new ObservableCollection<ProcessParametersTable>();
        }

        public class ParameterIndex
        {
            public String Name { get; set; }
            public int Index { get; set; }
        }

        private static int _counter = 0;

        public event EventHandler<ProcessParametersTable> PushParametersPressed;

        private ProcessParametersTable _processParameters;
        /// <summary>
        /// Gets or sets the process parameters.
        /// </summary>
        public ProcessParametersTable ProcessParameters
        {
            get { return _processParameters; }
            set { _processParameters = value; RaisePropertyChangedAuto(); }
        }

        /// <summary>
        /// Gets or sets the parameters indices.
        /// </summary>
        public List<ParameterIndex> ParametersIndices { get; set; }

        /// <summary>
        /// Gets or sets the push parameters command.
        /// </summary>
        [XmlIgnore]
        public RelayCommand PushParametersCommand { get; set; }

        private Rml _selectedResetRml;
        /// <summary>
        /// Gets or sets the selected reset RML.
        /// </summary>
        [XmlIgnore]
        public Rml SelectedResetRML
        {
            get { return _selectedResetRml; }
            set { _selectedResetRml = value; RaisePropertyChangedAuto(); ResetToRMLCommand.RaiseCanExecuteChanged(); }
        }


        /// <summary>
        /// Gets or sets the push parameters command.
        /// </summary>
        [XmlIgnore]
        public RelayCommand ResetToRMLCommand { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProcessParametersItem"/> class.
        /// </summary>
        public ProcessParametersItem() : base()
        {
            ParametersIndices = new List<ParameterIndex>();
            Name = "Process Parameters";
            Description = "Process parameters table";
            Image = ResourceHelper.GetImageFromResources("Images/process-params.png");
            ProcessParameters = new ProcessParametersTable();
            ProcessParameters.Name = "Process parameters " + _counter++;
            Color = Colors.DodgerBlue;
            PushParametersCommand = new RelayCommand(() => PushParametersPressed?.Invoke(this, ProcessParameters));

            ResetToRMLCommand = new RelayCommand(ResetToRml, () => SelectedResetRML != null);

            if (_counter > 1)
            {
                String name = ProcessParameters.Name;
                ProcessParametersTables.Add(ProcessParameters);
                ProcessParameters.Name = name;
            }
        }

        private void ResetToRml()
        {
            if (SelectedResetRML != null)
            {
                using (ObservablesContext db = ObservablesContext.CreateDefault())
                {
                    var group = db.Adapter.GetRmlActiveProcessParametersTablesGroup(SelectedResetRML.Guid);

                    if (group != null)
                    {
                        var table = group.ProcessParametersTables.OrderBy(x => x.TableIndex).FirstOrDefault();

                        if (table != null)
                        {
                            table.MapPrimitivesTo(ProcessParameters);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProcessParametersItem"/> class.
        /// </summary>
        /// <param name="processParameters">The process parameters.</param>
        public ProcessParametersItem(ProcessParametersTable processParameters) : this()
        {

        }

        public override TechItem Clone()
        {
            ProcessParametersItem cloned = base.Clone() as ProcessParametersItem;
            cloned.ProcessParameters = ProcessParameters.Clone();
            cloned.ParametersIndices = ParametersIndices.Select(x => new ParameterIndex() { Index = x.Index, Name = x.Name }).ToList();
            return cloned;
        }

    }
}
get { return _isInSession; } private set { _isInSession = value; RaisePropertyChangedAuto(); } } /// <summary> /// Gets the current session login intent. /// </summary> public ExternalBridgeLoginIntent SessionIntent { get; private set; } #endregion #region Constructors /// <summary> /// Initializes a new instance of the <see cref="ExternalBridgeService"/> class. /// </summary> public ExternalBridgeService() { _tcpServer = new TcpServer(1984); _tcpServer.ClientConnected += _tcpServer_ClientConnected; LogManager.NewLog += LogManager_NewLog; } /// <summary> /// Initializes a new instance of the <see cref="ExternalBridgeService"/> class. /// </summary> /// <param name="machineOperator">The machine operator.</param> /// <param name="machine">The machine.</param> public ExternalBridgeService(IMachineOperator machineOperator, Machine machine) : this() { Machine = machine; MachineOperator = machineOperator; } #endregion #region Properties Changes /// <summary> /// Called when the machine has been changed /// </summary> protected virtual void OnMachineChanged() { if (_discoverySevice != null && _discoverySevice.IsStarted) { _discoverySevice.Stop(); } _discoverySevice = new UdpDiscoveryService<ExternalBridgeUdpDiscoveryPacket>(8888, new ExternalBridgeUdpDiscoveryPacket() { SerialNumber = Machine.SerialNumber, }); } /// <summary> /// Called when the machine operator has been changed /// </summary> protected virtual void OnMachineOperatorChanged() { if (MachineOperator != null) { MachineOperator.StateChanged -= MachineOperator_StateChanged; MachineOperator.StateChanged += MachineOperator_StateChanged; } } #endregion #region Event Handlers /// <summary> /// Handles the ClientConnected event of the _tcpServer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="ClientConnectedEventArgs"/> instance containing the event data.</param> private async void _tcpServer_ClientConnected(object sender, ClientConnectedEventArgs e) { LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress()); Adapter = new TcpTransportAdapter(e.Socket); await Connect(); } /// <summary> /// Machines the operator state changed. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> private void MachineOperator_StateChanged(object sender, TransportComponentState e) { //Do nothing right now. } private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e) { if (State == TransportComponentState.Connected && _send_app_logs) { try { SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { LogItem = ByteString.CopyFrom(e.Serialize()) }, _app_logs_token); } catch { } } } #endregion #region Public Methods /// <summary> /// Starts this instance. /// </summary> public void Start() { if (!IsStarted) { _tcpServer.Start(); _discoverySevice.Start(); IsStarted = true; _enabled = true; RaisePropertyChanged(nameof(Enabled)); } } /// <summary> /// Stops this instance. /// </summary> public async void Stop() { if (IsStarted) { _tcpServer.Stop(); _discoverySevice.Stop(); IsStarted = false; IsInSession = false; _enabled = false; RaisePropertyChanged(nameof(Enabled)); try { await Disconnect(); } catch { } } } /// <summary> /// Disconnects the current remote client session. /// </summary> public async void DisconnectSession() { await Disconnect(); } #endregion #region Override Methods protected override void OnRequestReceived(MessageContainer container) { base.OnRequestReceived(container); try { if (Enabled) { if (container.Type == MessageType.ConnectRequest || container.Type == MessageType.DisconnectRequest) { //Do nothing ! } else if (container.Type == MessageType.ExternalBridgeLoginRequest) { OnExternalBridgeLoginRequest(container); } else if (container.Type == MessageType.ExternalBridgeLogoutRequest) { OnExternalBridgeLogoutRequest(container); } else if (container.Type == MessageType.StartApplicationLogsRequest) { _app_logs_token = container.Token; _send_app_logs = true; SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), container.Token); } else if (container.Type == MessageType.StopApplicationLogsRequest) { _send_app_logs = false; SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse() { }, container.Token); SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { }, _app_logs_token, true); } else { if (IsInSession && SessionIntent == ExternalBridgeLoginIntent.Override) { OnAnyRequest(container); } } } } catch (Exception ex) { LogManager.Log(ex, String.Format("An error occurred while processing a request message '{0}' from the remote host.", container.Type)); } } public async override Task Disconnect() { _send_app_logs = false; try { if (IsInSession) { await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5)); } } catch (Exception ex) { LogManager.Log(ex, "Error sending an external bridge log out request."); } finally { ClearQueues(); } OnClientDisconnected(); } #endregion #region Virtual Methods protected async virtual void OnClientDisconnected() { IsInSession = false; _send_app_logs = false; if (MachineOperator.State == TransportComponentState.Connected) { try { await MachineOperator.SendRequest(new StopDiagnosticsRequest()); } catch (Exception ex) { LogManager.Log(ex); } try { await MachineOperator.SendRequest(new StopDebugLogRequest()); } catch (Exception ex) { LogManager.Log(ex); } } ClientDisconnected?.Invoke(this, new EventArgs()); try { await base.Disconnect(); } catch (Exception ex) { LogManager.Log(ex); } LogManager.Log("External bridge client disconnected."); } #endregion #region Message Handlers protected virtual async void OnAnyRequest(MessageContainer container) { if (MachineOperator.Status == MachineStatuses.Disconnected) { try { await SendErrorResponse(new Exception("Machine operator is disconnected."), container.Token); } catch { } return; } if (!container.Continuous) { try { var response = await MachineOperator.SendRequest(container); await SendResponse(response); } //catch (TimeoutException) //{ //} catch (Exception ex) { await SendErrorResponse(ex, container.Token); } } else { MachineOperator.SendContinuousRequest(container).Subscribe((response) => { if (Enabled && IsInSession) { SendResponse(response); } }, (ex) => { if (Enabled) { if (ex is ResponseErrorException) { SendResponse((ex as ResponseErrorException).Container); } } }); } } protected async virtual void OnExternalBridgeLogoutRequest(MessageContainer container) { try { await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token); } catch (Exception ex) { LogManager.Log(ex); } finally { ClearQueues(); } OnClientDisconnected(); } protected async virtual void OnExternalBridgeLoginRequest(MessageContainer container) { var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container); LogManager.Log(String.Format("External bridge login attempt:{0}{1}", Environment.NewLine, request.Message.ToJsonString())); if (MachineOperator.Status != MachineStatuses.Printing || request.Message.Intent != ExternalBridgeLoginIntent.Override) { ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs(); args.Request = request; args.IpAddress = Adapter.Address; ConnectionRequest?.Invoke(this, args); var response = new ExternalBridgeLoginResponse(); response.Authenticated = args.Confirmed; response.SerialNumber = Machine.SerialNumber; response.DeviceInformation = MachineOperator.DeviceInformation; IsInSession = args.Confirmed; if (IsInSession) { LogManager.Log("External bridge client has logged-in successfully."); MachineOperator.EnableDiagnostics = false; MachineOperator.EnableEmbeddedDebugging = false; SessionIntent = request.Message.Intent; } else { LogManager.Log("External bridge client login failed, invalid password."); } await SendResponse<ExternalBridgeLoginResponse>(response, container.Token); } else { LogManager.Log("External bridge client login failed because the machine is currently printing."); await SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, "Machine connection override is not permitted while printing."); } } #endregion } }